55 EVENT_STREAM_RESPONSE_HEADER ,
66 isEventStreamResponse ,
77} from "../stream.ts" ;
8+ import { createServerTimings , type ServerTimingsBuilder } from "../timings.ts" ;
89import { serializeUint8Array } from "../util/buffers.ts" ;
910import { isUpgrade , makeWebSocket } from "../util/channels/channel.ts" ;
1011import { invokeNameAndMethod } from "../util/locator.ts" ;
@@ -50,6 +51,7 @@ export interface InvokeMiddlewareOptions {
5051 args : unknown [ ] ;
5152 metadata : unknown ;
5253 request : Request ;
54+ timings : ServerTimingsBuilder ;
5355}
5456
5557export type InvokeMiddleware = (
@@ -67,11 +69,16 @@ const hasInvokeMiddleware = (
6769
6870const invokeResponse = async (
6971 url : URL ,
70- options : InvokeOptions < any > & { request : Request } ,
72+ options : InvokeOptions < any > & {
73+ request : Request ;
74+ timings : ServerTimingsBuilder ;
75+ } ,
7176) : Promise < Response > => {
7277 try {
7378 const { request : req } = options ;
79+ const invokeTiming = options . timings . start ( "invoke" ) ;
7480 const res = await invoke ( options ) ;
81+ invokeTiming . end ( ) ;
7582 if ( isUpgrade ( res ) && req . headers . get ( "upgrade" ) === "websocket" ) {
7683 const { socket, response } = upgradeWebSocket ( req ) ;
7784 const chunkSize = url . searchParams . get ( STUB_MAX_CHUNK_SIZE_QS_NAME ) ;
@@ -179,18 +186,21 @@ export const server = <T extends object>(
179186 instanceCreator : ( name : string , req : Request ) => Promise < T > ,
180187) : ( req : Request ) => Promise < Response > => {
181188 return async ( req : Request ) => {
189+ const timings = createServerTimings ( ) ;
190+ using _ = timings . start ( "actor-entire-request" ) ;
182191 const url = new URL ( req . url ) ;
183192 const locator = invokeNameAndMethod ( url . pathname ) ;
184193
185194 if ( ! locator ) {
186195 return new Response ( null , { status : 404 } ) ;
187196 }
188197
198+ const instanceCreatorTiming = timings . start ( "actor-instance-creator" ) ;
189199 const objInstance = await instanceCreator (
190200 locator . name ,
191201 req ,
192202 ) ;
193-
203+ instanceCreatorTiming . end ( ) ;
194204 const { name : stubName , method : stubMethod } = locator ;
195205 if ( ! stubMethod || ! stubName ) {
196206 return new Response (
@@ -227,18 +237,36 @@ export const server = <T extends object>(
227237 metadata = parsedArgs . metadata ;
228238 }
229239 const next = ( mid : InvokeMiddlewareOptions ) => {
240+ const invokeResponseTiming = mid . timings . start ( "invoke-response" ) ;
230241 return invokeResponse ( url , {
231242 instance : objInstance ,
232243 stubName,
233244 methodName : mid . method ,
234245 args : mid . args ,
235246 metadata : mid . metadata ,
236247 request : mid . request ,
248+ timings : mid . timings ,
249+ } ) . finally ( ( ) => invokeResponseTiming . end ( ) ) . then ( ( res ) => {
250+ try {
251+ res . headers . set ( "server-timing" , mid . timings . printTimings ( ) ) ;
252+ } catch {
253+ // some headers are immutable
254+ }
255+ return res ;
237256 } ) ;
238257 } ;
239- const options = { args, metadata, request : req , method : stubMethod } ;
258+ const options = {
259+ args,
260+ metadata,
261+ request : req ,
262+ method : stubMethod ,
263+ timings,
264+ } ;
240265 if ( hasInvokeMiddleware ( objInstance ) ) {
241- return objInstance . onBeforeInvoke ( options , next ) ;
266+ const onBeforeInvokeTiming = timings . start ( "on-before-invoke" ) ;
267+ return objInstance . onBeforeInvoke ( options , next ) . finally ( ( ) =>
268+ onBeforeInvokeTiming . end ( )
269+ ) ;
242270 }
243271 return next ( options ) ;
244272 } ;
0 commit comments