@@ -4,13 +4,17 @@ import {
44 readableStreamFromIterable ,
55 SubProcess ,
66 type SubprocessErrorData ,
7+ trace ,
8+ context ,
9+ Context ,
710} from "../../deps.ts" ;
8- import { getTraceContext } from "../../gcp-tracing.ts" ;
911
1012import { templateHtml , makeErrorResponse , HtmlHeaders } from '../../lib/request-handling.ts' ;
1113import { findModuleSlug , resolveModuleUrl } from "../../lib/resolve.ts" ;
1214import { computeGraph , renderGraph } from "./compute.ts" ;
1315
16+ const tracer = trace . getTracer ( 'dependencies-of-api' ) ;
17+
1418export async function * handleRequest ( req : Request , modSlug : string , args : URLSearchParams ) {
1519 if ( modSlug == '' ) {
1620 const url = args . get ( 'url' ) ;
@@ -78,20 +82,15 @@ const hideLoadMsg = `<style type="text/css">#graph-waiting { display: none; }</s
7882
7983async function serveHtmlGraphPage ( req : Request , modUrl : string , modSlug : string , args : URLSearchParams ) {
8084 args . set ( 'font' , 'Archivo Narrow' ) ;
81- const ctx = getTraceContext ( ) ! ;
8285
8386 // Render the basic page first, so we can error more cleanly if that fails
8487 let pageHtml = '' ;
8588 try {
86- pageHtml = await ctx . enterSpan ( {
87- spanKind : 'INTERNAL' ,
88- displayName : { value : 'Render page HTML' } ,
89- startTime : new Date ( ) . toISOString ( ) ,
90- } , ( ) => templateHtml ( 'feat/dependencies-of/public.html' , {
89+ pageHtml = await templateHtml ( 'feat/dependencies-of/public.html' , {
9190 module_slug : entities . encode ( modSlug ) ,
9291 module_url : entities . encode ( modUrl ) ,
9392 export_prefix : entities . encode ( `${ req . url } ${ req . url . includes ( '?' ) ? '&' : '?' } format=` ) ,
94- } ) ) ;
93+ } ) ;
9594 } catch ( err ) {
9695 return makeErrorResponse ( err ) ;
9796 }
@@ -149,28 +148,44 @@ async function serveHtmlGraphPage(req: Request, modUrl: string, modSlug: string,
149148 } ) ;
150149
151150 // Return the body in two parts, with a comment in between
152- return new Response ( readableStreamFromIterable ( ( async function * ( ) {
151+
152+ async function * bodyGenerator ( ) {
153153 try {
154154 const encoder = new TextEncoder ( ) ;
155155 yield encoder . encode ( pageHtml ) ;
156156
157157 yield encoder . encode ( "\n<!-- now waiting for graph ... " ) ;
158158 const d0 = Date . now ( ) ;
159- const graphText = await ctx . enterSpan ( {
160- spanKind : "INTERNAL" ,
161- startTime : new Date ( ) . toISOString ( ) ,
162- displayName : { value : "Wait for graph text" } ,
163- } , async ( ) => hideLoadMsg + await graphPromise ) ;
159+ const span = tracer . startSpan ( 'Wait for graph text' ) ;
160+ const graphText = hideLoadMsg + await graphPromise . finally ( ( ) => span . end ( ) ) ;
164161 const millis = Date . now ( ) - d0 ;
165162 yield encoder . encode ( `completed in ${ millis } ms -->\n\n` ) ;
166163
167164 yield encoder . encode ( graphText ) ;
168-
169- ctx . spans [ 0 ] . endTime = new Date ( ) . toISOString ( ) ; // TODO: ugh
170165 } catch ( err ) {
171166 console . error ( err )
172167 }
173- } ( ) ) ) , {
168+ }
169+
170+ const bodyIterable = asyncGeneratorWithContext ( context . active ( ) , bodyGenerator ) ;
171+ return new Response ( readableStreamFromIterable ( bodyIterable ) , {
174172 headers : HtmlHeaders ,
175173 } ) ;
176174}
175+
176+ async function * asyncGeneratorWithContext < T , TReturn , TNext > (
177+ operationContext : Context ,
178+ operation : ( ) => AsyncGenerator < T , TReturn , TNext > ,
179+ ) : AsyncGenerator < T , TReturn , TNext > {
180+ const generator = context . with ( operationContext , operation )
181+ const next = context . bind ( operationContext , generator . next . bind ( generator ) )
182+
183+ let result : IteratorResult < T , TReturn > = await next ( )
184+
185+ while ( ! result . done ) {
186+ const nextParam = yield result . value
187+ result = await next ( nextParam )
188+ }
189+
190+ return result . value
191+ }
0 commit comments