DanielMSchmidt/apollo-opentracing

Allow distinguishing between different indexes of array fields

DanielMSchmidt opened this issue · 7 comments

With the implementation added in #83 we have this problem introduced as a shortcut to get a better version out sooner.

The underlying problem is given this query

{
  query: {
	list: {
  		value      
    }
  } 
}

and given that list is an array of three we would have these span relationships:

  • list => value times three as we call it for each of the array elements

The goal would be to have something like this:

  • list => [0] => value
  • list => [1] => value
  • list => [2] => value

That way we would have a clear separation which item took longest, which might be interesting as they might be of different types.

Implementation

To implement this we would need to start a new span once we enter such an array and finish it once we close on the array. We would most likely need to work a lot with the info argument, specifically the selectionSet.

Is this really that useful? I expect that another span should expose why one index was slow?

Let's say you load 3 items, but your implementation has different sources for each of the items to resolve them. You would not see the loading of the three items, but only a delay and then having all the field resolvers a little later for these. Does this make sense?

Something like this or am I missing it completely?

resolver(parent, context, args, info) {
  const list = [];
  const span = info.span;

  // data source 1
  ds1Span = tracer.startSpan(parent: span)
  list.push(... get data from source 1)
  ds1Span.finish()

  // data source 2
  ds2Span = tracer.startSpan(parent: span)
  list.push(... get data from source 2)
  ds2Span.finish()

  return list;
}

Yeah, I think you got it. If I see it right there is no real way for the library to know where exactly the data fetching starts. We need to think about how we can help our users to give us this data, I think

What I did in my prototype was to just use the next parent (loop through each possible parent, until no possible parent is left), and fall back to requestSpan.
And to make reading the output easier I used the full path as the span-name for everything. (not super ideal, but did the trick for me).

In any case, when you resolve the array, that data usually comes from the same source, and should take equally long to resolve. Each type on the other hand, might have things that resolve with different resolvers, but those instances will still be caught and put into the tracer correctly.

Edit: My comment above is about a simple resolver for the array, not where you actually use different sources, and in that case, I agree with @cliedeman that it's like in his example.

I disagree with the assumption that it's gonna come from the same source, but I think the current solution, which is what you described, falling back to the next available one is good enough for now.

I'll think about ideas and share them on how to enable more fine grained queries

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.