Skip to content

Commit 287508b

Browse files
committed
update graphql
1 parent 62677f6 commit 287508b

File tree

2 files changed

+79
-65
lines changed

2 files changed

+79
-65
lines changed

packages/datadog-instrumentations/src/graphql.js

Lines changed: 40 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -88,28 +88,28 @@ function wrapParse (parse) {
8888
return parse.apply(this, arguments)
8989
}
9090

91-
const ctx = {}
91+
const ctx = { source }
9292
return parseStartCh.runStores(ctx, () => {
93-
let document
9493
try {
95-
document = parse.apply(this, arguments)
96-
const operation = getOperation(document)
94+
ctx.document = parse.apply(this, arguments)
95+
const operation = getOperation(ctx.document)
9796

98-
if (!operation) return document
97+
if (!operation) return ctx.document
9998

10099
if (source) {
101-
documentSources.set(document, source.body || source)
100+
documentSources.set(ctx.document, source.body || source)
102101
}
102+
ctx.docSource = documentSources.get(ctx.document)
103103

104-
return document
104+
return ctx.document
105105
} catch (err) {
106106
err.stack
107107
ctx.error = err
108108
parseErrorCh.publish(ctx)
109109

110110
throw err
111111
} finally {
112-
parseFinishCh.publish({ source, document, docSource: documentSources.get(document), ...ctx })
112+
parseFinishCh.publish(ctx)
113113
}
114114
})
115115
}
@@ -138,7 +138,8 @@ function wrapValidate (validate) {
138138

139139
throw err
140140
} finally {
141-
validateFinishCh.publish({ errors, ...ctx })
141+
ctx.errors = errors
142+
validateFinishCh.publish(ctx)
142143
}
143144
})
144145
}
@@ -159,7 +160,14 @@ function wrapExecute (execute) {
159160
const contextValue = args.contextValue
160161
const operation = getOperation(document, args.operationName)
161162

162-
const ctx = { operation, args, docSource: documentSources.get(document) }
163+
const ctx = {
164+
operation,
165+
args,
166+
docSource: documentSources.get(document),
167+
source,
168+
fields: {},
169+
abortController: new AbortController()
170+
}
163171
return startExecuteCh.runStores(ctx, () => {
164172
if (contexts.has(contextValue)) {
165173
return exe.apply(this, arguments)
@@ -170,12 +178,10 @@ function wrapExecute (execute) {
170178
wrapFields(schema._mutationType)
171179
}
172180

173-
const context = { source, fields: {}, abortController: new AbortController(), ...ctx }
174-
175-
contexts.set(contextValue, context)
181+
contexts.set(contextValue, ctx)
176182

177-
return callInAsyncScope(exe, this, arguments, context.abortController, (err, res) => {
178-
if (finishResolveCh.hasSubscribers) finishResolvers(context)
183+
return callInAsyncScope(exe, this, arguments, ctx.abortController, (err, res) => {
184+
if (finishResolveCh.hasSubscribers) finishResolvers(ctx)
179185

180186
const error = err || (res && res.errors && res.errors[0])
181187

@@ -198,14 +204,17 @@ function wrapResolve (resolve) {
198204
function resolveAsync (source, args, contextValue, info) {
199205
if (!startResolveCh.hasSubscribers) return resolve.apply(this, arguments)
200206

201-
const context = contexts.get(contextValue)
207+
const ctx = contexts.get(contextValue)
202208

203-
if (!context) return resolve.apply(this, arguments)
209+
if (!ctx) return resolve.apply(this, arguments)
204210

205-
const field = assertField(context, info, args)
211+
const field = assertField(ctx, info, args)
206212

207-
return callInAsyncScope(resolve, this, arguments, context.abortController, (err) => {
208-
updateFieldCh.publish({ field, info, err, ...field.ctx })
213+
return callInAsyncScope(resolve, this, arguments, ctx.abortController, (err) => {
214+
field.ctx.error = err
215+
field.ctx.info = info
216+
field.ctx.field = field
217+
updateFieldCh.publish(field.ctx)
209218
})
210219
}
211220

@@ -250,49 +259,28 @@ function pathToArray (path) {
250259
return flattened.reverse()
251260
}
252261

253-
function assertField (context, info, args) {
262+
function assertField (parentCtx, info, args) {
254263
const pathInfo = info && info.path
255264

256265
const path = pathToArray(pathInfo)
257266

258267
const pathString = path.join('.')
259-
const fields = context.fields
268+
const fields = parentCtx.fields
260269

261270
let field = fields[pathString]
262271

263272
if (!field) {
264-
const parent = getParentField(context, path)
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)
273+
const fieldCtx = { info, ctx: parentCtx, args }
274+
startResolveCh.publish(fieldCtx)
269275
field = fields[pathString] = {
270-
parent,
271276
error: null,
272-
ctx
277+
ctx: fieldCtx
273278
}
274279
}
275280

276281
return field
277282
}
278283

279-
function getParentField (context, path) {
280-
for (let i = path.length - 1; i > 0; i--) {
281-
const field = getField(context, path.slice(0, i))
282-
if (field) {
283-
return field
284-
}
285-
}
286-
287-
return {
288-
asyncResource: context.asyncResource
289-
}
290-
}
291-
292-
function getField (context, path) {
293-
return context.fields[path.join('.')]
294-
}
295-
296284
function wrapFields (type) {
297285
if (!type || !type._fields || patchedTypes.has(type)) {
298286
return
@@ -328,12 +316,14 @@ function wrapFieldType (field) {
328316
function finishResolvers ({ fields }) {
329317
Object.keys(fields).reverse().forEach(key => {
330318
const field = fields[key]
331-
const ctx = { field, finishTime: field.finishTime, ...field.ctx }
319+
field.ctx.finishTime = field.finishTime
320+
field.ctx.field = field
332321
if (field.error) {
333-
ctx.error = field.error
334-
resolveErrorCh.publish(ctx)
322+
field.ctx.error = field.error
323+
resolveErrorCh.publish(field.ctx)
335324
}
336-
finishResolveCh.publish(ctx)
325+
console.log('finishResolvers', field)
326+
finishResolveCh.publish(field.ctx)
337327
})
338328
}
339329

packages/datadog-plugin-graphql/src/resolve.js

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,35 @@ class GraphQLResolvePlugin extends TracingPlugin {
99
static get id () { return 'graphql' }
1010
static get operation () { return 'resolve' }
1111

12-
start (ctx) {
13-
const { info, context, args, childOf } = ctx
14-
const path = getPath(info, this.config)
12+
start (fieldCtx) {
13+
const { info, ctx: parentCtx, args } = fieldCtx
14+
15+
const pathInfo = info && info.path
16+
const path = pathToArray(pathInfo)
17+
18+
// we need to get the parent span to the field if it exists for correct span parenting
19+
// of nested fields
20+
const parentField = getParentField(parentCtx, path)
21+
const childOf = parentField?.ctx?.currentStore?.span
22+
23+
fieldCtx.parent = parentField
1524

1625
if (!shouldInstrument(this.config, path)) return
1726
const computedPathString = path.join('.')
1827

1928
if (this.config.collapse) {
20-
if (context.fields[computedPathString]) return
29+
if (parentCtx.fields[computedPathString]) return
2130

22-
if (!context[collapsedPathSym]) {
23-
context[collapsedPathSym] = {}
24-
} else if (context[collapsedPathSym][computedPathString]) {
31+
if (!parentCtx[collapsedPathSym]) {
32+
parentCtx[collapsedPathSym] = {}
33+
} else if (parentCtx[collapsedPathSym][computedPathString]) {
2534
return
2635
}
2736

28-
context[collapsedPathSym][computedPathString] = true
37+
parentCtx[collapsedPathSym][computedPathString] = true
2938
}
3039

31-
const document = context.source
40+
const document = parentCtx.source
3241
const fieldNode = info.fieldNodes.find(fieldNode => fieldNode.kind === 'Field')
3342
const loc = this.config.source && document && fieldNode && fieldNode.loc
3443
const source = loc && document.slice(loc.start, loc.end)
@@ -44,7 +53,7 @@ class GraphQLResolvePlugin extends TracingPlugin {
4453
'graphql.field.type': info.returnType.name,
4554
'graphql.source': source
4655
}
47-
}, ctx)
56+
}, fieldCtx)
4857

4958
if (fieldNode && this.config.variables && fieldNode.arguments) {
5059
const variables = this.config.variables(info.variableValues)
@@ -58,25 +67,25 @@ class GraphQLResolvePlugin extends TracingPlugin {
5867
}
5968

6069
if (this.resolverStartCh.hasSubscribers) {
61-
this.resolverStartCh.publish({ context, resolverInfo: getResolverInfo(info, args) })
70+
this.resolverStartCh.publish({ ctx: parentCtx, resolverInfo: getResolverInfo(info, args) })
6271
}
6372

64-
return ctx.currentStore
73+
return fieldCtx.currentStore
6574
}
6675

6776
constructor (...args) {
6877
super(...args)
6978

7079
this.addTraceSub('updateField', (ctx) => {
71-
const { field, info, err } = ctx
80+
const { field, info, error } = ctx
7281

7382
const path = getPath(info, this.config)
7483

7584
if (!shouldInstrument(this.config, path)) return
7685

7786
const span = ctx?.currentStore?.span || this.activeSpan
7887
field.finishTime = span._getTime ? span._getTime() : 0
79-
field.error = field.error || err
88+
field.error = field.error || error
8089
})
8190

8291
this.resolverStartCh = dc.channel('datadog:graphql:resolver:start')
@@ -87,7 +96,7 @@ class GraphQLResolvePlugin extends TracingPlugin {
8796
super.configure(config.depth === 0 ? false : config)
8897
}
8998

90-
bindFinish (ctx) {
99+
finish (ctx) {
91100
const { finishTime } = ctx
92101

93102
const span = ctx?.currentStore?.span || this.activeSpan
@@ -165,4 +174,19 @@ function getResolverInfo (info, args) {
165174
return resolverInfo
166175
}
167176

177+
function getParentField (parentCtx, path) {
178+
for (let i = path.length - 1; i > 0; i--) {
179+
const field = getField(parentCtx, path.slice(0, i))
180+
if (field) {
181+
return field
182+
}
183+
}
184+
185+
return null
186+
}
187+
188+
function getField (parentCtx, path) {
189+
return parentCtx.fields[path.join('.')]
190+
}
191+
168192
module.exports = GraphQLResolvePlugin

0 commit comments

Comments
 (0)