-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
create a metadata envelope for nodes #369
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not requesting changes because I think they are more open design questions about if/when we should do some things.
@@ -68,7 +69,14 @@ func execPipeline(ctx context.Context, in *graph.Graph, pipelineF MkPipelineF, r | |||
notify.Transform(func(id string, out *graph.Graph) error { | |||
renderingPlant.Graph = out | |||
pipeline := pipelineF(out, id) | |||
val, pipelineError := pipeline.Exec(out.Get(id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are using the ID inside of the pipeline, does it make sense to actually go ahead and pass the entire node into the pipeline instead of extracting it, then pull the ID from the node rather than putting it into the pipeline?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would that look like? I'm having a hard time understanding what you're saying here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inside of apply/pipeline
we have:
type pipelineGen struct {
Graph *graph.Graph
ID string
RenderingPlant *render.Factory
}
and
func Pipeline(g *graph.Graph, id string, factory *render.Factory) executor.Pipeline {
gen := &pipelineGen{Graph: g, RenderingPlant: factory, ID: id}
since the ID is now going to be part of the element we could remove the ID from pipelineGen
and the call to Pipeline
. It's not necessarily hurting anything to have it as it is, but it does get us down to a single source-of-truth for the ID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, that seems like it would be a good future addition. One of the optimizations we've been talking about, yeah?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah that's fair 👍
pipeline := Pipeline(out, id, renderingPlant) | ||
val, pipelineErr := pipeline.Exec(out.Get(id)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As with apply- does it make sense to pass the entire node in here and handle it correctly inside the pipeline?
} | ||
|
||
// New creates a new node | ||
func New(id string, value interface{}) *Node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've noticed that we have a general pattern of at each phase in the processing pipeline (load
,render
,plan
,and apply
) we create a new *Node
, with the ID and value. That works for now but it does require that we have knowlege that the id and value are the only relevant fields in the node, and that nothing earlier in the pipeline has added useful metadata.
Would it make sense to have a func (n *Node) SetValue(newValue interface{}) {
that would set the value, or else a func (n *Node) Transform(func (interface{}) (interface{}, error) ) (*Node, error)
that transforms the value inside of the node, so that later phases of the processing pipeline can update the inner value without losing accumulated metadata information?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, we need to not lose accumulated metadata… SetValue
works but it means we're mutating the nodes. We could copy them, of course, but that essentially means throwing away an entire graph at every stage. I'm not sure what the right solution is. Since our processing only goes forward and never forks, mutating might make sense. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the idea of copying because it doesn't feel like the size of the graph is going to be large enough that it's going to introduce enormous overhead; we already replace the node at each stage so we'd only be introducing the addition of copying the metadata which doesn't seem like it should be all that much extra?
Also in the absence of a compelling reason to mutate I'd say that we're better to prefer copying just to avoid bugs related to parallel execution- I don't really have any specific case in mind where that would happen but it does just seem like the sort of thing.
8bbac28
to
14a9975
Compare
Doesn't include tests yet
I'm minimizing this interface to prepare for a smallish PR. Coordinates should be added again in the future.
14a9975
to
e7fbad8
Compare
LGTM on green |
create a metadata envelope for nodes
These changes are enable future expansion in the following:
Points of interest in this PR:
graph/node/node.go
)graph.Get
return value changes frominterface{}
to(meta *node.Node, ok bool)
. This is basically removingGet
in favor ofMaybeGet
andrenaming/reworking everything to use the new return value.
graph.GetParent
return value changes frominterface{}
to(meta *node.Node, ok bool)
in the same way.interface{}
to*node.Node
This PR changes a whole lot of stuff, but it's all in service of the changes
above. This might cause some integration headaches but should improve failure
detection, since call sites now have to explicitly handle missing nodes (they
didn't before, oops)