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,10 +88,8 @@ 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 ( )
91
+ const ctx = { }
92
+ return parseStartCh . runStores ( ctx , ( ) => {
96
93
let document
97
94
try {
98
95
document = parse . apply ( this , arguments )
@@ -107,11 +104,12 @@ function wrapParse (parse) {
107
104
return 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 ( { source, document, docSource : documentSources . get ( document ) , ... ctx } )
115
113
}
116
114
} )
117
115
}
@@ -123,25 +121,24 @@ 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
+ validateFinishCh . publish ( { errors , ... ctx } )
145
142
}
146
143
} )
147
144
}
@@ -155,15 +152,15 @@ function wrapExecute (execute) {
155
152
return exe . apply ( this , arguments )
156
153
}
157
154
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 )
155
+ const args = normalizeArgs ( arguments , defaultFieldResolver )
156
+ const schema = args . schema
157
+ const document = args . document
158
+ const source = documentSources . get ( document )
159
+ const contextValue = args . contextValue
160
+ const operation = getOperation ( document , args . operationName )
166
161
162
+ const ctx = { operation, args, docSource : documentSources . get ( document ) }
163
+ return startExecuteCh . runStores ( ctx , ( ) => {
167
164
if ( contexts . has ( contextValue ) ) {
168
165
return exe . apply ( this , arguments )
169
166
}
@@ -173,26 +170,22 @@ function wrapExecute (execute) {
173
170
wrapFields ( schema . _mutationType )
174
171
}
175
172
176
- startExecuteCh . publish ( {
177
- operation,
178
- args,
179
- docSource : documentSources . get ( document )
180
- } )
181
-
182
- const context = { source, asyncResource, fields : { } , abortController : new AbortController ( ) }
173
+ const context = { source, fields : { } , abortController : new AbortController ( ) , ...ctx }
183
174
184
175
contexts . set ( contextValue , context )
185
176
186
- return callInAsyncScope ( exe , asyncResource , this , arguments , context . abortController , ( err , res ) => {
177
+ return callInAsyncScope ( exe , this , arguments , context . abortController , ( err , res ) => {
187
178
if ( finishResolveCh . hasSubscribers ) finishResolvers ( context )
188
179
189
180
const error = err || ( res && res . errors && res . errors [ 0 ] )
190
181
191
182
if ( error ) {
192
- executeErrorCh . publish ( error )
183
+ ctx . error = error
184
+ executeErrorCh . publish ( ctx )
193
185
}
194
186
195
- finishExecuteCh . publish ( { res, args, context } )
187
+ ctx . res = res
188
+ finishExecuteCh . publish ( ctx )
196
189
} )
197
190
} )
198
191
}
@@ -211,8 +204,8 @@ function wrapResolve (resolve) {
211
204
212
205
const field = assertField ( context , info , args )
213
206
214
- return callInAsyncScope ( resolve , field . asyncResource , this , arguments , context . abortController , ( err ) => {
215
- updateFieldCh . publish ( { field, info, err } )
207
+ return callInAsyncScope ( resolve , this , arguments , context . abortController , ( err ) => {
208
+ updateFieldCh . publish ( { field, info, err, ... field . ctx } )
216
209
} )
217
210
}
218
211
@@ -221,32 +214,30 @@ function wrapResolve (resolve) {
221
214
return resolveAsync
222
215
}
223
216
224
- function callInAsyncScope ( fn , aR , thisArg , args , abortController , cb ) {
217
+ function callInAsyncScope ( fn , thisArg , args , abortController , cb ) {
225
218
cb = cb || ( ( ) => { } )
226
219
227
- return aR . runInAsyncScope ( ( ) => {
228
- if ( abortController ?. signal . aborted ) {
229
- cb ( null , null )
230
- throw new AbortError ( 'Aborted' )
231
- }
220
+ if ( abortController ?. signal . aborted ) {
221
+ cb ( null , null )
222
+ throw new AbortError ( 'Aborted' )
223
+ }
232
224
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
225
+ try {
226
+ const result = fn . apply ( thisArg , args )
227
+ if ( result && typeof result . then === 'function' ) {
228
+ // bind callback to this scope
229
+ result . then (
230
+ res => cb ( null , res ) ,
231
+ err => cb ( err )
232
+ )
233
+ } else {
234
+ cb ( null , result )
248
235
}
249
- } )
236
+ return result
237
+ } catch ( err ) {
238
+ cb ( err )
239
+ throw err
240
+ }
250
241
}
251
242
252
243
function pathToArray ( path ) {
@@ -271,27 +262,15 @@ function assertField (context, info, args) {
271
262
272
263
if ( ! field ) {
273
264
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
- } )
265
+ // we need to pass the parent span to the field if it exists for correct span parenting
266
+ // of nested fields
267
+ const ctx = { info, context, args, childOf : parent ?. ctx ?. currentStore ?. span }
268
+ startResolveCh . publish ( ctx )
269
+ field = fields [ pathString ] = {
270
+ parent,
271
+ error : null ,
272
+ ctx
273
+ }
295
274
}
296
275
297
276
return field
@@ -349,20 +328,16 @@ function wrapFieldType (field) {
349
328
function finishResolvers ( { fields } ) {
350
329
Object . keys ( fields ) . reverse ( ) . forEach ( key => {
351
330
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
- } )
331
+ const ctx = { field, finishTime : field . finishTime , ...field . ctx }
332
+ if ( field . error ) {
333
+ ctx . error = field . error
334
+ resolveErrorCh . publish ( ctx )
335
+ }
336
+ finishResolveCh . publish ( ctx )
359
337
} )
360
338
}
361
339
362
- addHook ( { name : '@graphql-tools/executor' , file : 'cjs/execution/execute.js' , versions : [ '>=0.0.14' ] } , execute => {
363
- shimmer . wrap ( execute , 'execute' , wrapExecute ( execute ) )
364
- return execute
365
- } )
340
+ addHook ( { name : '@graphql-tools/executor' , file : 'cjs/execution/execute.js' , versions : [ '>=0.0.14' ] } , execute => { } )
366
341
367
342
addHook ( { name : 'graphql' , file : 'execution/execute.js' , versions : [ '>=0.10' ] } , execute => {
368
343
shimmer . wrap ( execute , 'execute' , wrapExecute ( execute ) )
0 commit comments