mirror of
https://github.com/oarkflow/mq.git
synced 2025-10-07 08:50:54 +08:00
109 lines
2.0 KiB
Go
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)
|
|
}
|