This page is a draft. Feedback is welcome.
Welcome to the heart of Pathom. The planner is the part of Pathom that figures which resolvers to call, in which order to fulfill the data demand.
What is a plan?
The Pathom plan is a DAG, and always has a single root.
Now we are going to a series of examples to understand how the planner does its job, and what it outputs.
To understand the planner, we going to walk though a series of examples:
The simplest plan
To compute the plan, Pathom requires:
In case you already have some data available, you can tell the planner about it using the Shape Descriptor, so it will consider that when formulating the plan.
For our first example, it's going to be a simple request that calls a single resolver:
Pathom represents the plan DAG using plain Clojure maps. Our previous example generate this graph:
To generate the plan, Pathom starts scanning the AST. For each attribute it sees, it
looks it up in the index. In case the attribute requires other dependencies, Pathom will
recursively walk the
index-oir until it finds the matches or reach a dead end.
Now it's time to introduce the planner, viz. This is a tool that lets you visualize a Pathom execution plan visually. This is also a tool to understand and debug how Pathom builds up a plan. Using the items on the left, you can navigate through the graph building process:
This tool still in the early stages. Expect changes to it.
Our current case is simple, a single resolver node.
Time to break down some of the attributes here:
It contains a map with all the nodes from this graph, indexed by
is a monotonic incremental value, the first node gets the ID 1.
In the planner graph, there are three types of possible nodes:
Represent a call to a resolver
Represent the call of multiple resolvers, also, being a sibling node in a AND node means the runner can call those nodes in parallel.
Represent that one of the nodes must get the required data.
Index pointing to the nodes for a given resolver.
The start node of the plan. In the visualization, the root node has a black border.
This index knows which node is responsible for a given attribute. This is important for internal optimizations, when some dependency appears repeated, Pathom can use this index to connect straight to a node, avoiding re-processing.
You can find spec definitions with descriptions for every property of the planner at the planner source code.
The next case we are going to look at is what happens when there are attribute dependencies.
To make these examples shorter, from now on, I'm going to use the
of the graph instead of writing the full resolvers. To start, let's look at our previous
example using the
index-oir I'm going to use short names for the convenience of the demonstration,
but keep in mind for real systems, its recommended to stick with long names.
The black arrow means the node
tau will run after the node for
AND nodes represent a set of nodes that all need to run. Also, the planner designs
the graph in a way that the runner can run all the nodes from an AND node in parallel
if desired. To see an example of that here is a plan for a query that asks for three
Now, to see a combination of AND node and chaining, let's ask for a single attribute
:d that requires
Note there are orange arrows and black arrows. The orange arrows run first (possibly in parallel), the black arrow only runs after all the orange arrows finish.
For cases when there is more than one option to fetch an attribute. In those cases, Pathom
OR node to express that. For this example, we will have three different resolvers
to the attribute
OR also uses orange arrows, but this time they mean at least once of the
edges must run, instead of all of them.
In the next example, we can see how Pathom deals with graphs that require different input paths:
Here you can see what happens when some request tries to find dependencies and reach a dead-end:
Now a partial dead-end, note how it discards the dead cluster on
Combined OR and AND
When combining those, you will see the
OR nodes get processed before the AND nodes.
And a more complex example:
You can use the following tool to play around with indexes and queries, and see how the planner will compute the plan for it:
You can pull the Index OIR from some environment: