Fork me on GitHub
#graphql
<
2022-10-11
>
enn20:10:18

I’m trying to understand how asynchronous field resolvers work with nested object types. Example:

type Department {
  head: Person!
}

type Person {
  name: String!
  dob: Instant!
  ...
}
Imagine a query selecting the name, dob etc of the department head. In this example the resolver for the Department head field returns a promise using resolve/resolve-promise, but the resolvers for Person name and dob do not explicitly return a promise. If the call to resolve/deliver! in the head resolver runs in a specific thread, do the resolvers for the name and dob fields run in the same thread? or in the main thread?

enn20:10:34

This https://github.com/walmartlabs/lacinia/issues/48#issuecomment-309859058 suggests that the Person field resolvers would not execute in the same thread as the head resolver, but it’s five years old and I’m not sure if that’s still true.

hlship21:10:23

The name and dob field resolvers will be executed in a pooled thread, but only once the promise delivers the head Person. Generally, they will run in the same thread (its more efficient that way) but if there was a field between them that returns a promise, that bet is off.

enn14:10:44

hmm, now I’m confused again. so if the head resolver looks like this:

(.execute my-threadpool #(l.resolve/deliver! p (do-stuff)))
are you saying that the name and dob resolvers will also run in my-threadpool, if they don’t do anything explicit to start a thread or return a promise, and if there was no field in between them?

hlship23:10:50

Sorry, no. Lacinia has its own thread pool for this stuff, and uses a dynamic Var to track if it's executing in a thread from that pool; it will use a thread from it's own pool even though deliver! was called from a pooled thread - but not a Lacinia pooled thread.

enn23:10:39

I see--@U09R86PA4 and I spent some time today looking at the Lacinia code and that is the conclusion we tentatively came to, but it's good to have it confirmed. This is helpful knowledge in figuring out how and where to use async resolvers, so thank you.

favila00:10:29

This seems to contract the docs which say the callback will run on the delivering thread (and that’s also what the code seems to do)

favila00:10:43

*contradict

favila00:10:07

Although i admit I am very turned around at this point