Files
mq/v2/dag.go
2024-10-08 14:53:31 +05:45

109 lines
2.0 KiB
Go

package v2
import (
"context"
"encoding/json"
"sync"
"github.com/oarkflow/xid"
)
type Handler func(ctx context.Context, task *Task) Result
type Result struct {
TaskID string `json:"task_id"`
Payload json.RawMessage `json:"payload"`
Status string `json:"status"`
Error error `json:"error"`
nodeKey string
}
type Task struct {
ID string `json:"id"`
NodeKey string `json:"node_key"`
Payload json.RawMessage `json:"payload"`
Results map[string]Result `json:"results"`
}
type Node struct {
Key string
Edges []Edge
handler Handler
}
type EdgeType int
const (
SimpleEdge EdgeType = iota
LoopEdge
)
type Edge struct {
From *Node
To *Node
Type EdgeType
}
type DAG struct {
Nodes map[string]*Node
taskContext map[string]*TaskManager
conditions map[string]map[string]string
mu sync.RWMutex
}
func NewDAG() *DAG {
return &DAG{
Nodes: make(map[string]*Node),
taskContext: make(map[string]*TaskManager),
conditions: make(map[string]map[string]string),
}
}
func (tm *DAG) AddNode(key string, handler Handler) {
tm.mu.Lock()
defer tm.mu.Unlock()
tm.Nodes[key] = &Node{
Key: key,
handler: handler,
}
}
func (tm *DAG) AddCondition(fromNode string, conditions map[string]string) {
tm.mu.Lock()
defer tm.mu.Unlock()
tm.conditions[fromNode] = conditions
}
func (tm *DAG) AddEdge(from, to string, edgeType EdgeType) {
tm.mu.Lock()
defer tm.mu.Unlock()
fromNode, ok := tm.Nodes[from]
if !ok {
return
}
toNode, ok := tm.Nodes[to]
if !ok {
return
}
fromNode.Edges = append(fromNode.Edges, Edge{
From: fromNode,
To: toNode,
Type: edgeType,
})
}
func (tm *DAG) ProcessTask(ctx context.Context, node string, payload []byte) Result {
tm.mu.Lock()
defer tm.mu.Unlock()
taskID := xid.New().String()
task := &Task{
ID: taskID,
NodeKey: node,
Payload: payload,
Results: make(map[string]Result),
}
manager := NewTaskManager(tm)
tm.taskContext[taskID] = manager
return manager.processTask(ctx, node, task)
}