2
2
3
3
const {
4
4
addHook,
5
- channel,
6
- AsyncResource
5
+ channel
7
6
} = require ( './helpers/instrument' )
8
7
const shimmer = require ( '../../datadog-shimmer' )
9
8
@@ -89,29 +88,28 @@ function wrapParse (parse) {
89
88
return parse . apply ( this , arguments )
90
89
}
91
90
92
- const asyncResource = new AsyncResource ( 'bound-anonymous-fn' )
93
-
94
- return asyncResource . runInAsyncScope ( ( ) => {
95
- parseStartCh . publish ( )
96
- let document
91
+ const ctx = { source }
92
+ return parseStartCh . runStores ( ctx , ( ) => {
97
93
try {
98
- document = parse . apply ( this , arguments )
99
- const operation = getOperation ( document )
94
+ ctx . document = parse . apply ( this , arguments )
95
+ const operation = getOperation ( ctx . document )
100
96
101
- if ( ! operation ) return document
97
+ if ( ! operation ) return ctx . document
102
98
103
99
if ( source ) {
104
- documentSources . set ( document , source . body || source )
100
+ documentSources . set ( ctx . document , source . body || source )
105
101
}
102
+ ctx . docSource = documentSources . get ( ctx . document )
106
103
107
- return document
104
+ return ctx . document
108
105
} catch ( err ) {
109
106
err . stack
110
- parseErrorCh . publish ( err )
107
+ ctx . error = err
108
+ parseErrorCh . publish ( ctx )
111
109
112
110
throw err
113
111
} finally {
114
- parseFinishCh . publish ( { source , document , docSource : documentSources . get ( document ) } )
112
+ parseFinishCh . publish ( ctx )
115
113
}
116
114
} )
117
115
}
@@ -123,25 +121,25 @@ function wrapValidate (validate) {
123
121
return validate . apply ( this , arguments )
124
122
}
125
123
126
- const asyncResource = new AsyncResource ( 'bound-anonymous-fn' )
127
-
128
- return asyncResource . runInAsyncScope ( ( ) => {
129
- validateStartCh . publish ( { docSource : documentSources . get ( document ) , document } )
130
-
124
+ const ctx = { docSource : documentSources . get ( document ) , document }
125
+ return validateStartCh . runStores ( ctx , ( ) => {
131
126
let errors
132
127
try {
133
128
errors = validate . apply ( this , arguments )
134
129
if ( errors && errors [ 0 ] ) {
135
- validateErrorCh . publish ( errors && errors [ 0 ] )
130
+ ctx . error = errors && errors [ 0 ]
131
+ validateErrorCh . publish ( ctx )
136
132
}
137
133
return errors
138
134
} catch ( err ) {
139
135
err . stack
140
- validateErrorCh . publish ( err )
136
+ ctx . error = err
137
+ validateErrorCh . publish ( ctx )
141
138
142
139
throw err
143
140
} finally {
144
- validateFinishCh . publish ( { document, errors } )
141
+ ctx . errors = errors
142
+ validateFinishCh . publish ( ctx )
145
143
}
146
144
} )
147
145
}
@@ -155,44 +153,46 @@ function wrapExecute (execute) {
155
153
return exe . apply ( this , arguments )
156
154
}
157
155
158
- const asyncResource = new AsyncResource ( 'bound-anonymous-fn' )
159
- return asyncResource . runInAsyncScope ( ( ) => {
160
- const args = normalizeArgs ( arguments , defaultFieldResolver )
161
- const schema = args . schema
162
- const document = args . document
163
- const source = documentSources . get ( document )
164
- const contextValue = args . contextValue
165
- const operation = getOperation ( document , args . operationName )
166
-
167
- if ( contexts . has ( contextValue ) ) {
168
- return exe . apply ( this , arguments )
169
- }
156
+ const args = normalizeArgs ( arguments , defaultFieldResolver )
157
+ const schema = args . schema
158
+ const document = args . document
159
+ const source = documentSources . get ( document )
160
+ const contextValue = args . contextValue
161
+ const operation = getOperation ( document , args . operationName )
162
+
163
+ if ( contexts . has ( contextValue ) ) {
164
+ return exe . apply ( this , arguments )
165
+ }
166
+
167
+ const ctx = {
168
+ operation,
169
+ args,
170
+ docSource : documentSources . get ( document ) ,
171
+ source,
172
+ fields : { } ,
173
+ abortController : new AbortController ( )
174
+ }
170
175
176
+ return startExecuteCh . runStores ( ctx , ( ) => {
171
177
if ( schema ) {
172
178
wrapFields ( schema . _queryType )
173
179
wrapFields ( schema . _mutationType )
174
180
}
175
181
176
- startExecuteCh . publish ( {
177
- operation,
178
- args,
179
- docSource : documentSources . get ( document )
180
- } )
181
-
182
- const context = { source, asyncResource, fields : { } , abortController : new AbortController ( ) }
183
-
184
- contexts . set ( contextValue , context )
182
+ contexts . set ( contextValue , ctx )
185
183
186
- return callInAsyncScope ( exe , asyncResource , this , arguments , context . abortController , ( err , res ) => {
187
- if ( finishResolveCh . hasSubscribers ) finishResolvers ( context )
184
+ return callInAsyncScope ( exe , this , arguments , ctx . abortController , ( err , res ) => {
185
+ if ( finishResolveCh . hasSubscribers ) finishResolvers ( ctx )
188
186
189
187
const error = err || ( res && res . errors && res . errors [ 0 ] )
190
188
191
189
if ( error ) {
192
- executeErrorCh . publish ( error )
190
+ ctx . error = error
191
+ executeErrorCh . publish ( ctx )
193
192
}
194
193
195
- finishExecuteCh . publish ( { res, args, context } )
194
+ ctx . res = res
195
+ finishExecuteCh . publish ( ctx )
196
196
} )
197
197
} )
198
198
}
@@ -205,14 +205,17 @@ function wrapResolve (resolve) {
205
205
function resolveAsync ( source , args , contextValue , info ) {
206
206
if ( ! startResolveCh . hasSubscribers ) return resolve . apply ( this , arguments )
207
207
208
- const context = contexts . get ( contextValue )
208
+ const ctx = contexts . get ( contextValue )
209
209
210
- if ( ! context ) return resolve . apply ( this , arguments )
210
+ if ( ! ctx ) return resolve . apply ( this , arguments )
211
211
212
- const field = assertField ( context , info , args )
212
+ const field = assertField ( ctx , info , args )
213
213
214
- return callInAsyncScope ( resolve , field . asyncResource , this , arguments , context . abortController , ( err ) => {
215
- updateFieldCh . publish ( { field, info, err } )
214
+ return callInAsyncScope ( resolve , this , arguments , ctx . abortController , ( err ) => {
215
+ field . ctx . error = err
216
+ field . ctx . info = info
217
+ field . ctx . field = field
218
+ updateFieldCh . publish ( field . ctx )
216
219
} )
217
220
}
218
221
@@ -221,32 +224,30 @@ function wrapResolve (resolve) {
221
224
return resolveAsync
222
225
}
223
226
224
- function callInAsyncScope ( fn , aR , thisArg , args , abortController , cb ) {
227
+ function callInAsyncScope ( fn , thisArg , args , abortController , cb ) {
225
228
cb = cb || ( ( ) => { } )
226
229
227
- return aR . runInAsyncScope ( ( ) => {
228
- if ( abortController ?. signal . aborted ) {
229
- cb ( null , null )
230
- throw new AbortError ( 'Aborted' )
231
- }
230
+ if ( abortController ?. signal . aborted ) {
231
+ cb ( null , null )
232
+ throw new AbortError ( 'Aborted' )
233
+ }
232
234
233
- try {
234
- const result = fn . apply ( thisArg , args )
235
- if ( result && typeof result . then === 'function' ) {
236
- // bind callback to this scope
237
- result . then (
238
- aR . bind ( res => cb ( null , res ) ) ,
239
- aR . bind ( err => cb ( err ) )
240
- )
241
- } else {
242
- cb ( null , result )
243
- }
244
- return result
245
- } catch ( err ) {
246
- cb ( err )
247
- throw err
235
+ try {
236
+ const result = fn . apply ( thisArg , args )
237
+ if ( result && typeof result . then === 'function' ) {
238
+ // bind callback to this scope
239
+ result . then (
240
+ res => cb ( null , res ) ,
241
+ err => cb ( err )
242
+ )
243
+ } else {
244
+ cb ( null , result )
248
245
}
249
- } )
246
+ return result
247
+ } catch ( err ) {
248
+ cb ( err )
249
+ throw err
250
+ }
250
251
}
251
252
252
253
function pathToArray ( path ) {
@@ -259,59 +260,26 @@ function pathToArray (path) {
259
260
return flattened . reverse ( )
260
261
}
261
262
262
- function assertField ( context , info , args ) {
263
+ function assertField ( rootCtx , info , args ) {
263
264
const pathInfo = info && info . path
264
265
265
266
const path = pathToArray ( pathInfo )
266
267
267
268
const pathString = path . join ( '.' )
268
- const fields = context . fields
269
+ const fields = rootCtx . fields
269
270
270
271
let field = fields [ pathString ]
271
272
272
273
if ( ! field ) {
273
- const parent = getParentField ( context , path )
274
-
275
- // we want to spawn the new span off of the parent, not a new async resource
276
- parent . asyncResource . runInAsyncScope ( ( ) => {
277
- /* this child resource will run a branched scope off of the parent resource, which
278
- accesses the parent span from the storage unit in its own scope */
279
- const childResource = new AsyncResource ( 'bound-anonymous-fn' )
280
-
281
- childResource . runInAsyncScope ( ( ) => {
282
- startResolveCh . publish ( {
283
- info,
284
- context,
285
- args
286
- } )
287
- } )
288
-
289
- field = fields [ pathString ] = {
290
- parent,
291
- asyncResource : childResource ,
292
- error : null
293
- }
294
- } )
295
- }
296
-
297
- return field
298
- }
299
-
300
- function getParentField ( context , path ) {
301
- for ( let i = path . length - 1 ; i > 0 ; i -- ) {
302
- const field = getField ( context , path . slice ( 0 , i ) )
303
- if ( field ) {
304
- return field
274
+ const fieldCtx = { info, rootCtx, args }
275
+ startResolveCh . publish ( fieldCtx )
276
+ field = fields [ pathString ] = {
277
+ error : null ,
278
+ ctx : fieldCtx
305
279
}
306
280
}
307
281
308
- return {
309
- asyncResource : context . asyncResource
310
- }
311
- }
312
-
313
- function getField ( context , path ) {
314
- return context . fields [ path . join ( '.' ) ]
282
+ return field
315
283
}
316
284
317
285
function wrapFields ( type ) {
@@ -349,13 +317,13 @@ function wrapFieldType (field) {
349
317
function finishResolvers ( { fields } ) {
350
318
Object . keys ( fields ) . reverse ( ) . forEach ( key => {
351
319
const field = fields [ key ]
352
- const asyncResource = field . asyncResource
353
- asyncResource . runInAsyncScope ( ( ) => {
354
- if ( field . error ) {
355
- resolveErrorCh . publish ( field . error )
356
- }
357
- finishResolveCh . publish ( field . finishTime )
358
- } )
320
+ field . ctx . finishTime = field . finishTime
321
+ field . ctx . field = field
322
+ if ( field . error ) {
323
+ field . ctx . error = field . error
324
+ resolveErrorCh . publish ( field . ctx )
325
+ }
326
+ finishResolveCh . publish ( field . ctx )
359
327
} )
360
328
}
361
329
0 commit comments