pathom

Dallas Surewood 2024-04-24T17:43:58.728089Z

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 priority

wilkerlucio 2024-04-30T19:43:18.191749Z

FYI: removed the bad example from documentation

Dallas Surewood 2024-04-25T12:44:38.329049Z

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?

nivekuil 2024-04-25T18:24:46.506629Z

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

nivekuil 2024-04-25T18:25:03.011569Z

same with any library/framework/abstraction

wilkerlucio 2024-04-25T18:25:47.744529Z

@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

wilkerlucio 2024-04-25T18:26:37.776649Z

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

wilkerlucio 2024-04-25T18:28:01.385129Z

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

wilkerlucio 2024-04-24T18:21:11.398579Z

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

wilkerlucio 2024-04-24T18:21:51.916719Z

we did had changes on the behavior of the path selection, so I'm guessing I made the example before the change was merged

Dallas Surewood 2024-04-24T18:37:20.948499Z

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

wilkerlucio 2024-04-24T18:39:01.743919Z

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

wilkerlucio 2024-04-24T18:42:38.879449Z

this was the change: https://github.com/wilkerlucio/pathom3/commit/ff2d4780c49f5f5628797a0787b0063b2e46fa8e

wilkerlucio 2024-04-24T18:43:49.408319Z

is this affecting the behavior you expected in your application? or its more a validation of the docs?

Dallas Surewood 2024-04-24T18:45:54.419799Z

More validation.

wilkerlucio 2024-04-24T18:46:23.360919Z

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

Dallas Surewood 2024-04-24T18:49:00.762409Z

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])

wilkerlucio 2024-04-24T18:53:26.170599Z

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

Dallas Surewood 2024-04-24T18:58:17.742079Z

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?

nivekuil 2024-04-24T22:54:16.206909Z

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])

Dallas Surewood 2024-04-24T23:37:46.941709Z

That returns a1 for me. The docs say it should return a2 because the dependency is a higher priority.

nivekuil 2024-04-24T23:53:46.426259Z

right, and that's the behavior you want right? the docs are just outdated

nivekuil 2024-04-24T23:54:39.470389Z

{:dep 2} is lower priority in my example than {:dep 1}

Dallas Surewood 2024-04-25T02:19:21.487239Z

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?

Dallas Surewood 2024-04-25T02:58:39.823019Z

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.

nivekuil 2024-04-25T04:27:14.953719Z

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

nivekuil 2024-04-25T04:27:36.202749Z

of course the best solution would just be to handle more complex logic in clojure rather than pathom

Dallas Surewood 2024-05-01T13:57:19.060269Z

Thank you!