-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtree.go
More file actions
93 lines (79 loc) · 2.31 KB
/
Copy pathtree.go
File metadata and controls
93 lines (79 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package apiflow
import (
"context"
"sync"
)
type State string
const (
StatePending = "pending"
StateSuccess = "success"
StateFailure = "failure"
)
type Failure string
const (
FailureExecute = "execute"
FailureTimeout = "timeout"
FailurePreError = "pre-error"
)
// Handler is a function associated with a node type
// It will be executed during traversal or as needed
// Returns an error to indicate failure
type Handler func(ctx context.Context, node *Node, inputs map[string]interface{}) (interface{}, error)
// Node represents a node in the dependency tree
// Each node corresponds to an API request
// If a node fails, all its dependents are marked as failed
type Node struct {
ID string // Unique identifier of the node
Predecessors map[string]*Node // Nodes that are dependencies of this node
Successors map[string]*Node // Nodes that depend on this node
Handler Handler // Handler function associated with the node
State State // "pending", "success", "failure"
Failure Failure
Data *NodeData // Data produced by this node
Mutex sync.Mutex // To protect state and data modifications
}
type NodeData struct {
Ptr interface{}
LazyByte []byte
}
// DependencyTree represents the entire tree structure
type DependencyTree struct {
nodes map[string]*Node // All nodes in the tree, indexed by their ID
}
// NewDependencyTree creates a new, empty dependency tree
func NewDependencyTree() *DependencyTree {
return &DependencyTree{
nodes: make(map[string]*Node),
}
}
// NewNode creates a new node without adding it to the tree
func NewNode(id string, handler Handler) *Node {
return &Node{
ID: id,
Predecessors: make(map[string]*Node),
Successors: make(map[string]*Node),
Handler: handler,
State: StatePending,
}
}
// AddNode adds a pre-created node to the dependency tree with its upstream dependencies
func (dt *DependencyTree) AddNode(node *Node, upstreamNodes []*Node) {
if _, exists := dt.nodes[node.ID]; exists {
return
}
dt.nodes[node.ID] = node
for _, n := range upstreamNodes {
if n == nil {
continue
}
if n.ID == "" {
continue
}
upstreamNode, exists := dt.nodes[n.ID]
if !exists {
continue
}
upstreamNode.Successors[node.ID] = node
node.Predecessors[n.ID] = upstreamNode
}
}