It seems like this example in the docs doesn't resolve to {:a 1} like it says. For me, it resolves to {:a 2} and doesn't care what the priority of dependencies are
(p.eql/process
(pci/register
[(pco/resolver 'high-priority-dep
{::pco/priority 5 ; very high priority
::pco/output [:dep]}
(fn [_ _] {:dep "value"}))
(pco/resolver 'a1
{::pco/priority 1
::pco/input [:dep]
::pco/output [:a]}
(fn [_ _]
{:a 1}))
; this is higher on priority than a1, and has no deps
(pco/resolver 'a2
{::pco/priority 2
::pco/output [:a]}
(fn [_ _]
{:a 2}))])
[:a])
; => {:a 1} ; the lower priority for `:a` won, because the `:dep` on that path had the highest priorityFYI: removed the bad example from documentation
of course the best solution would just be to handle more complex logic in clojure rather than pathomI usually see Pathom pitched as a way to handle complex logic better. If you feel Clojure is better for complex logic, what use cases do you think Pathom are good for?
pathom gives you a lot of complex logic for free, but if you can spare the effort and complexity it's always better to hand code stuff for explicitness and performance
same with any library/framework/abstraction
@sdata374 one thing, is that, the part of path selection is something you can override, you can define in your env your strategy and make something that's different from what Pathom provides by default
another idea in this space, is that in Pathom 2 it used to have a dynamic path selector, that considered the average time spent by each resolver, so when it sees a path, it estimates the cost of the whole path (add avg time of each resolver that's part of it) and pick that path, we can port that to Pathom 3 as well
but really depends on what you expect from it (that might change on each case), maybe you have for example some service taht provides state data and its more reliable, but you only wanna use that if your main resolver is failing to get the result, its hard to predict at library level what kind of behavior you need in such cases
hello Dallas, can you please link me the example you found? in this case I believe the behavior is correct (maybe the example you found was wrong). because Pathom will consider the highest priority number in a given path, so that high-priority-dep will cause that path to be taken
we did had changes on the behavior of the path selection, so I'm guessing I made the example before the change was merged
Locally, the path with high-priority-dep wasn't taken, that would be {:a 1}.
It's the second example https://pathom3.wsscode.com/docs/resolvers#priority-number
humm, thanks for pointing it out, its been a while since I see this, but maybe the change was from what I described, to focusing on the priority of the target attribute
this was the change: https://github.com/wilkerlucio/pathom3/commit/ff2d4780c49f5f5628797a0787b0063b2e46fa8e
is this affecting the behavior you expected in your application? or its more a validation of the docs?
More validation.
I need to refresh the context in my head, but I think the current behavior has been proven more general, so its likely that I'll be fixing the docs
It looks like dependency prioritization is not taken into account anymore. It looks like it's just about the current nodes being compared and what the shortest path is. Might not need that section anymore.
below returns {:b 2} even though {:b 1} has a very high priority dependency.
(p.eql/process
(pci/register
[(pco/resolver 'a1
{::pco/priority 99 ;; High Priority
::pco/output [:a1]}
(fn [_ _]
{:a1 1}))
(pco/resolver 'a2
{::pco/priority 1
::pco/output [:a2]}
(fn [_ _]
{:a2 2}))
(pco/resolver 'b1
{::pco/input [:a1]
::pco/output [:b]}
(fn [_ _]
{:b 1}))
(pco/resolver 'b2
{::pco/input [:a2]
::pco/output [:b]}
(fn [_ _]
{:b 2}))])
[:b])yeah, in any case, I think I can extend the docs to explain better how it works, its been 2 years now since it was implemented, faded in my head at this point
It sounds like this is a fairly unused part of the library. I figured this was the only way to make sure I am using the most efficient resolvers for the task I need, but it sounds like that's not the case. For instance, say I had two resolvers that each got a bunch of user data, and I'm querying. a third resolver that depends on user data. Either user resolver could work, but one is way slower than the other. What should I be doing in this case to make sure I can query without worrying about inefficient resolvers being prioritized?
the current behavior seems correct, and your use case of same data with different priority resolvers should just work today
(p.eql/process
(pci/register
[(pco/resolver 'high-priority-dep
{::pco/priority 10 ; very high priority
::pco/output [:dep]}
(fn [_ _] {:dep 1}))
(pco/resolver 'a1
{::pco/priority 1
::pco/output [:dep]}
(fn [_ _]
{:dep 2}))
(pco/resolver 'a2
{::pco/input [:dep]
::pco/output [:a]}
(fn [_ {:keys [dep]}]
{:a dep}))])
[:a])That returns a1 for me. The docs say it should return a2 because the dependency is a higher priority.
right, and that's the behavior you want right? the docs are just outdated
{:dep 2} is lower priority in my example than {:dep 1}
I didn't necessarily want one or the other. But I am wondering if that's the only way to handle competing paths for a query. In an ideal world, we would be able to query something and not worry about whether it took a slower path than needed (more network roundtrips or complex queries). If the thing I'm trying to get relies on user data and there's two ways to get that, I'd like it to do the quickest way. Is the way to do that right now just priority numbers?
I ask because the more I'm using it, the less it makes sense what the default resolution of resolvers are and I'm wondering if there's a way to specify it more directly.
iirc it's undefined, but there was some idea around tracing execution times/costs and dynamically changing paths based on that. but priority is simple, explicit, and works
of course the best solution would just be to handle more complex logic in clojure rather than pathom
Thank you!