2018-03-21 20:43:21 +01:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation. All rights reserved.
|
2017-01-18 00:57:24 +01:00
|
|
|
|
2018-03-04 22:34:20 +01:00
|
|
|
// Package graph defines resource graphs. Each graph is directed and acyclic, and the nodes have been topologically
|
2017-01-18 00:57:24 +01:00
|
|
|
// sorted based on dependencies (edges) between them. Each node in the graph has a type and a set of properties.
|
|
|
|
//
|
|
|
|
// There are two forms of graph: complete and incomplete. A complete graph is one in which all nodes and their property
|
|
|
|
// values are known. An incomplete graph is one where two uncertainties may arise: (1) an edge might be "conditional",
|
|
|
|
// indicating that its presence or absence is dependent on a piece of information not yet available (like an output
|
|
|
|
// property from a resource), and/or (2) a property may either be similarly conditional or computed as an output value.
|
|
|
|
//
|
2018-03-04 22:34:20 +01:00
|
|
|
// In general, programs may be evaluated to produce graphs. These may then be compared to other graphs to produce
|
2017-01-18 00:57:24 +01:00
|
|
|
// and/or carry out deployment plans. This package therefore also exposes operations necessary for diffing graphs.
|
|
|
|
package graph
|
|
|
|
|
2018-03-04 22:34:20 +01:00
|
|
|
// Graph is an instance of a resource digraph. Each is associated with a single program input, along
|
2017-02-25 16:25:33 +01:00
|
|
|
// with a set of optional arguments used to evaluate it, along with the output DAG with node types and properties.
|
2017-01-18 00:57:24 +01:00
|
|
|
type Graph interface {
|
2017-02-18 19:22:04 +01:00
|
|
|
Roots() []Edge // the root edges.
|
2017-01-18 00:57:24 +01:00
|
|
|
}
|
2017-02-13 23:26:46 +01:00
|
|
|
|
2018-03-04 22:34:20 +01:00
|
|
|
// Vertex is a single vertex within an overall resource graph.
|
2017-02-13 23:26:46 +01:00
|
|
|
type Vertex interface {
|
Implement updates
This change is a first whack at implementing updates.
Creation and deletion plans are pretty straightforward; we just take
a single graph, topologically sort it, and perform the operations in
the right order. For creation, this is in dependency order (things
that are depended upon must be created before dependents); for deletion,
this is in reverse-dependency order (things that depend on others must
be deleted before dependencies). These are just special cases of the more
general idea of performing DAG operations in dependency order.
Updates must work in terms of this more general notion. For example:
* It is an error to delete a resource while another refers to it; thus,
resources are deleted after deleting dependents, or after updating
dependent properties that reference the resource to new values.
* It is an error to depend on a create a resource before it is created;
thus, resources must be created before dependents are created, and/or
before updates to existing resource properties that would cause them
to refer to the new resource.
Of course, all of this is tangled up in a graph of dependencies. As a
result, we must create a DAG of the dependencies between creates, updates,
and deletes, and then topologically sort this DAG, in order to determine
the proper order of update operations.
To do this, we slightly generalize the existing graph infrastructure,
while also specializing two kinds of graphs; the existing one becomes a
heapstate.ObjectGraph, while this new one is resource.planGraph (internal).
2017-02-23 23:56:23 +01:00
|
|
|
Data() interface{} // arbitrary data associated with this vertex.
|
|
|
|
Label() string // the vertex's label.
|
|
|
|
Ins() []Edge // incoming edges from other vertices within the graph to this vertex.
|
|
|
|
Outs() []Edge // outgoing edges from this vertex to other vertices within the graph.
|
2017-02-13 23:26:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Edge is a directed edge from one vertex to another.
|
|
|
|
type Edge interface {
|
Implement updates
This change is a first whack at implementing updates.
Creation and deletion plans are pretty straightforward; we just take
a single graph, topologically sort it, and perform the operations in
the right order. For creation, this is in dependency order (things
that are depended upon must be created before dependents); for deletion,
this is in reverse-dependency order (things that depend on others must
be deleted before dependencies). These are just special cases of the more
general idea of performing DAG operations in dependency order.
Updates must work in terms of this more general notion. For example:
* It is an error to delete a resource while another refers to it; thus,
resources are deleted after deleting dependents, or after updating
dependent properties that reference the resource to new values.
* It is an error to depend on a create a resource before it is created;
thus, resources must be created before dependents are created, and/or
before updates to existing resource properties that would cause them
to refer to the new resource.
Of course, all of this is tangled up in a graph of dependencies. As a
result, we must create a DAG of the dependencies between creates, updates,
and deletes, and then topologically sort this DAG, in order to determine
the proper order of update operations.
To do this, we slightly generalize the existing graph infrastructure,
while also specializing two kinds of graphs; the existing one becomes a
heapstate.ObjectGraph, while this new one is resource.planGraph (internal).
2017-02-23 23:56:23 +01:00
|
|
|
Data() interface{} // arbitrary data associated with this edge.
|
|
|
|
Label() string // this edge's label.
|
|
|
|
To() Vertex // the vertex this edge connects to.
|
|
|
|
From() Vertex // the vertex this edge connects from.
|
2018-02-23 02:31:45 +01:00
|
|
|
Color() string // an optional color for this edge, for when this graph is displayed.
|
2017-02-13 23:26:46 +01:00
|
|
|
}
|