I'm having trouble getting Pathom(3) to make use of batch resolvers. I seem to be fulfilling the criteria for batch resolvers to kick in (maps are returned, or rather, a vector of maps), but Pathom seems to split them into individual calls anyway. I'm not sure what to look for while investigating this issue, what should I be looking out for?
can you share some code? we use batch resolvers on pathom3 and havent’ had such problem.
good to hear about this case
I've been giving second thoughs around the plugins, because batching also suffers from the limitations of the "wrapping pattern"
its also interesting to think about what is a good way to provide hooks for metrics like this
because measuring single vs batch, its not the same thing, and maybe is better to have distint ways to track it
That’s a good point, and it’s not the end of the world if it's two separate hooks. To me, it doesn't matter for the purposes of Honeycomb, since it's interesting enough to see where the app is spending a lot of time. From that point of view, it doesn't matter whether it’s batched or not. But I get that there may be other circumstances where it does matter.
With Honeycomb, I could inject the variable of whether it's batched or not, if this distinction could be known inside the plugin definition. This would enable me to split the analysis on those that are batched and not in the Honeycomb UI. Exposing an indicator of whether the plug-in is currently running inside a batch resolver or not might be more convenient than using two distinct integration points. That would leave it up to the creator of the plug-in to decide whether this information matters to them or not.
currently you can check if you look at the resolver, the "node" has ::pco/op-name
, which you can use to lookup at ::pci/index-resolvers
, them pull the config map with pco/operation-config
the major missing point is a hook to know about the batch run time
that's currenty not available, but I can add that, just like to think a bit more about the whole plugin thing, this is something I can get to this week
@henrik yesterday I made some changes to what wrap-resolve
wraps, before it was wrapping some higher process, but now it really wraps the resolve
call (as I believe you expected, which makes sense), note now you get env input
instead of env node
, please let me know how that fits in your game
important to note though, now in the case of batch, you will only get 1 call to wrap-resolve
with the batch (`input` will be a collection)
This works very well, thank you. I can now add the size of the input to the logging with Honeycomb. (i.e., "it took 59ms, but on the other hand there were 2291 inputs")
hello Henrik, looking at the graph it seems to be using batch correctly, that blue bar is kind of a “shared time” in the batch of the items
have you tried logging to see if there are many calls to the resolver?
maybe the reading is a bit confusing, but see that those blue bars are in "parallel", altough there is no parallel runner yet, the intention was to make an indication they are a single thing (the batch run), do you have an idea how we could make this clear?
Aha! That's interesting. I've also written a plugin to wrap each resolver call with a log to Honeycomb, where it looks like it's registering numerous calls to the same resolver:
Now I'm thinking that I might not be measuring what I think I'm measuring. When wrapping around ::pcr/wrap-resolve
, am I wrapping around the call to the resolver, or the construction of the resolver, or something else?
(Btw, Honeycomb might be an example of a UX that is quite good at communicating where spans are children vs. siblings)
(defn wrap-resolver-with-honeycomb [resolve]
(fn [env node]
(wrap-honeycomb env (str (::pco/op-name node))
(resolve env node))))
So, It's pretty clear to me that I've misunderstood wrap-resolve
, and that this is the source of my confusion.
Is there a way to wrap the invocation of a resolver, at the moment where it receives the inputs?
this expectation is correct, but as you are seeing, in the case of batch it get some caveats
indeed it always runs when the resolver gets the input, but, in the case of batch, it doesn't run immediatly
you can check if that happen, by looking at the output of what you are wrapping, in case of batch it will be a map with the key ::pcr/batch-hold
on it, if you see that, this means the resolver isn't running now, and will run later as a batch
for observability purposes, you may want to ignore those cases
honeycomb looks nice 🙂