Fork me on GitHub
#pathom
<
2022-02-17
>
Hukka14:02:11

Does Pathom have any concept of different potential ways to get from A to B? Say for example that A is a Product, that has manufacturer, id, and name. We want to know the cost. For some products we have a database from names to costs. But for some other products we need to query the manufacturer's system with the id to get the cost, and with some we just cannot get the cost in any way.

markaddleman14:02:49

Yes. Our app uses this. It's not a specific feature, per se. It's simply an outcome of how Pathom works.

markaddleman14:02:19

In a nutshell, "resolvers" declare their inputs and their outputs.

markaddleman14:02:58

A client makes a query for a particular output and Pathom computes a "plan" to obtain the result. The plan can have many branches reflecting all the possible ways that the result could be computed given the input from the client's query.

markaddleman14:02:48

I think it's useful to think of Pathom as automated, dynamic function composition.

Ivan14:02:09

afaik, this goes a bit further in the sense that the choice of which path will be followed first is based on calculating a cost for that data access

Hukka15:02:24

Sure, but how would I describe that one resolver needs name, outputs cost. Second needs manufacturer and id, outputs cost. But neither might, or might not be able to produce the cost, so both need to be tried, in a given order.

Hukka15:02:58

I could of course make one resolver that takes all three as input, but that wouldn't work in cases where for example the name is not available

markaddleman15:02:57

I'm not aware of cost-based planning. Pathom uses a sort mechanism (I believe you could create a dynamic sorting capability which could mimic cost based sorting but this would require extending Pathom)

markaddleman15:02:15

@U8ZQ1J1RR I have almost exactly your use case. Suppose you have two resolvers that can product cost. You can provide Pathom the order in which the resolvers should be tried using the priority system. If the first resolver cannot compute cost, it simply returns nil. Pathom will automatically try the second resolver.

Hukka15:02:31

Great. Is it just the order which the index is created? Is the seq accessed in from first to last, last to first or pop order (so vectors and lists work differently)?

Hukka16:02:53

Ok, so return ::pco/unknown-value, from the higher priority resolver and Pathom will try the next one. At least as long as the paths are equal length (the discussion seems to show that things get confused in other cases)

markaddleman16:02:54

Yes, that's correct. In practice, I generally write mutually exclusive guarding if statements on each resolver so I don't have to worry about path length.

mauricio.szabo18:02:04

@U8ZQ1J1RR I also have the same situation at an open-source project, but honestly, if you do need to follow a specific order, the "default priorization" of Pathom does not help too much, honestly - it easily gets into some weird cases when it does not what you expect. More info here: https://github.com/wilkerlucio/pathom3/discussions/57

Hukka18:02:08

Thanks, yeah. That's the discussion I was referring to, and the path length differences.

mauricio.szabo18:02:22

I just posted how I kinda solved the issue on the discussion now, if you want to check 🙂

wilkerlucio21:02:57

the current prioritization is flacky as @U3Y18N0UC, and just to be clear we are talking Pathom 3, Pathom 2 by default uses a prioritization based on "path weight", to do this pathom tracks the time that resolvers are taking to run (dynamically, it updates this value every time a resolver gets called), so it will choose the path that has the least weight (for example, you may have a path with 5 resolvers that take 3ms each, vs a path with 1 resolver that takes 100ms, in this case the path with 5 resolvers still better)

wilkerlucio21:02:06

I'm planning to bring that back to Pathom 3 and make that the default prioritization mechanism again, that said, this part of the algorithm is extensible, so you can plug you own prioritization function if you want (like Mauricio did). and I'm open for other general ideas to make prioritization work, I didn't had a chance to look closer in the latest mauricio one, but it could be that 🙂

❤️ 1
wilkerlucio21:02:35

@U3Y18N0UC do you think the one you are using is general enough to be part of the library? what you see as limitations of it at this point?

mauricio.szabo21:02:45

@U066U8JQJ the only limitation that I see is that I didn't battle-test it yet. It seems to be working fine in my case, and I'm not seeing anything weird happening so far, and the code is generic enough. But it was mostly a "let's try this, hey, it works!" than "let's analyze all possible cases" 🙂

mauricio.szabo21:02:42

The code is literally "let me get the keys that I expect from the or-node", then "let me get all successors that provide these keys", and them sort by the one with maximum priority

wilkerlucio00:02:53

@U8ZQ1J1RR the algorithm from@U3Y18N0UC just landed on main in Pathom 3! I'll cut a new release including it tomorrow (its the new default, I replaced the old one with it)

mauricio.szabo14:02:34

Wow, glad to see that it worked! 🙂

🚀 1
Eric Dvorsak11:10:19

I think the issue I mentioned above might be related to this thread. I'll dive into the code to see if there's a small fix. Essentially the issue is that in the absence of any priority OR branches the sorting doesn't prioritize the shortest path

Eric Dvorsak12:10:12

ok so I found the solution. The weight of the branch isn't taken into account unless one registers the resolver-weight-tracker. When it is not there, the first item in the set returned by the prioritization is used. I think that a small improvement would be to still take weight into account, with a default of 1 for each node when there is multiple candidates returned by the prioritization