@@ -94,6 +94,9 @@ async function handleApiCall(url, request, env) {
9494// This is where the requests for the worker come in. They can either be pure API requests or
9595// requests to set up a session with a Durable Object through a Yjs WebSocket.
9696export async function handleApiRequest ( request , env ) {
97+ let timingDaAdminHeadDuration ;
98+ const timingStartTime = Date . now ( ) ;
99+
97100 // We've received a pure API request - handle it and return.
98101 const url = new URL ( request . url ) ;
99102 if ( url . pathname . startsWith ( '/api/' ) ) {
@@ -127,7 +130,9 @@ export async function handleApiRequest(request, env) {
127130 opts . headers = new Headers ( { Authorization : auth } ) ;
128131 }
129132
133+ const timingBeforeDaAdminHead = Date . now ( ) ;
130134 const initialReq = await env . daadmin . fetch ( docName , opts ) ;
135+ timingDaAdminHeadDuration = Date . now ( ) - timingBeforeDaAdminHead ;
131136
132137 if ( ! initialReq . ok && initialReq . status !== 404 ) {
133138 // eslint-disable-next-line no-console
@@ -140,6 +145,7 @@ export async function handleApiRequest(request, env) {
140145 return new Response ( 'unable to get resource' , { status : 500 } ) ;
141146 }
142147
148+ const timingBeforeDocRoomGet = Date . now ( ) ;
143149 // Each Durable Object has a 256-bit unique ID. Route the request based on the path.
144150 const id = env . rooms . idFromName ( docName ) ;
145151
@@ -150,11 +156,17 @@ export async function handleApiRequest(request, env) {
150156 // created on-demand when the ID is first used, there's nothing to wait for anyway; we know
151157 // an object will be available somewhere to receive our requests.
152158 const roomObject = env . rooms . get ( id ) ;
159+ const timingDocRoomGetDuration = Date . now ( ) - timingBeforeDocRoomGet ;
153160
154161 // eslint-disable-next-line no-console
155162 console . log ( `FETCHING: ${ docName } ${ id } ` ) ;
156163
157- const headers = [ ...request . headers , [ 'X-collab-room' , docName ] ] ;
164+ const headers = [ ...request . headers ,
165+ [ 'X-collab-room' , docName ] ,
166+ [ 'X-timing-start' , timingStartTime ] ,
167+ [ 'X-timing-da-admin-head-duration' , timingDaAdminHeadDuration ] ,
168+ [ 'X-timing-docroom-get-duration' , timingDocRoomGetDuration ] ,
169+ ] ;
158170 if ( auth ) {
159171 headers . push ( [ 'Authorization' , auth ] ) ;
160172 }
@@ -248,6 +260,7 @@ export class DocRoom {
248260 return new Response ( 'expected docName' , { status : 400 } ) ;
249261 }
250262
263+ const timingBeforeSetupWebsocket = Date . now ( ) ;
251264 // To accept the WebSocket request, we create a WebSocketPair (which is like a socketpair,
252265 // i.e. two WebSockets that talk to each other), we return one end of the pair in the
253266 // response, and we operate on the other end. Note that this API is not part of the
@@ -256,10 +269,20 @@ export class DocRoom {
256269 const pair = DocRoom . newWebSocketPair ( ) ;
257270
258271 // We're going to take pair[1] as our end, and return pair[0] to the client.
259- await this . handleSession ( pair [ 1 ] , docName , auth ) ;
272+ const timingData = await this . handleSession ( pair [ 1 ] , docName , auth ) ;
273+ const timingSetupWebSocketDuration = Date . now ( ) - timingBeforeSetupWebsocket ;
274+
275+ const reqHeaders = request . headers ;
276+ const respheaders = new Headers ( ) ;
277+ respheaders . set ( 'X-1-timing-da-admin-head-duration' , reqHeaders . get ( 'X-timing-da-admin-head-duration' ) ) ;
278+ respheaders . set ( 'X-2-timing-docroom-get-duration' , reqHeaders . get ( 'X-timing-docroom-get-duration' ) ) ;
279+ respheaders . set ( 'X-4-timing-da-admin-get-duration' , timingData . get ( 'timingDaAdminGetDuration' ) ) ;
280+ respheaders . set ( 'X-5-timing-read-state-duration' , timingData . get ( 'timingReadStateDuration' ) ) ;
281+ respheaders . set ( 'X-7-timing-setup-websocket-duration' , timingSetupWebSocketDuration ) ;
282+ respheaders . set ( 'X-9-timing-full-duration' , Date . now ( ) - reqHeaders . get ( 'X-timing-start' ) ) ;
260283
261284 // Now we return the other end of the pair to the client.
262- return new Response ( null , { status : successCode , webSocket : pair [ 0 ] } ) ;
285+ return new Response ( null , { status : successCode , headers : respheaders , webSocket : pair [ 0 ] } ) ;
263286 }
264287
265288 /**
@@ -277,6 +300,7 @@ export class DocRoom {
277300 // eslint-disable-next-line no-console
278301 console . log ( `setupWSConnection ${ docName } with auth(${ webSocket . auth
279302 ? webSocket . auth . substring ( 0 , webSocket . auth . indexOf ( ' ' ) ) : 'none' } )`) ;
280- await setupWSConnection ( webSocket , docName , this . env , this . storage ) ;
303+ const timingData = await setupWSConnection ( webSocket , docName , this . env , this . storage ) ;
304+ return timingData ;
281305 }
282306}
0 commit comments