mirror of
https://github.com/oarkflow/mq.git
synced 2025-10-06 08:26:52 +08:00
init: publisher
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -14,25 +15,33 @@ func main() {
|
|||||||
dag := NewDAG()
|
dag := NewDAG()
|
||||||
dag.AddNode("queue1", func(ctx context.Context, task mq.Task) mq.Result {
|
dag.AddNode("queue1", func(ctx context.Context, task mq.Task) mq.Result {
|
||||||
log.Printf("Handling task for queue1: %s", string(task.Payload))
|
log.Printf("Handling task for queue1: %s", string(task.Payload))
|
||||||
return mq.Result{Payload: []byte(`[{"user_id": 1}, {"user_id": 2}]`), MessageID: task.ID}
|
return mq.Result{Payload: task.Payload, MessageID: task.ID}
|
||||||
})
|
})
|
||||||
dag.AddNode("queue2", func(ctx context.Context, task mq.Task) mq.Result {
|
dag.AddNode("queue2", func(ctx context.Context, task mq.Task) mq.Result {
|
||||||
var item map[string]interface{}
|
log.Printf("Handling task for queue2: %s", string(task.Payload))
|
||||||
if err := json.Unmarshal(task.Payload, &item); err != nil {
|
return mq.Result{Payload: task.Payload, MessageID: task.ID}
|
||||||
return mq.Result{Payload: nil, Error: err, MessageID: task.ID}
|
})
|
||||||
}
|
dag.AddNode("queue3", func(ctx context.Context, task mq.Task) mq.Result {
|
||||||
item["salary"] = 12000 // Simulating task logic by adding "salary"
|
var data map[string]any
|
||||||
result, _ := json.Marshal(item)
|
err := json.Unmarshal(task.Payload, &data)
|
||||||
log.Printf("Handling task for queue2: %s", string(result))
|
if err != nil {
|
||||||
return mq.Result{Payload: result, MessageID: task.ID}
|
return mq.Result{Error: err}
|
||||||
|
}
|
||||||
|
data["salary"] = fmt.Sprintf("12000%v", data["user_id"])
|
||||||
|
bt, _ := json.Marshal(data)
|
||||||
|
log.Printf("Handling task for queue3: %s", string(task.Payload))
|
||||||
|
return mq.Result{Payload: bt, MessageID: task.ID}
|
||||||
|
})
|
||||||
|
dag.AddNode("queue4", func(ctx context.Context, task mq.Task) mq.Result {
|
||||||
|
log.Printf("Handling task for queue4: %s", string(task.Payload))
|
||||||
|
return mq.Result{Payload: task.Payload, MessageID: task.ID}
|
||||||
})
|
})
|
||||||
|
|
||||||
dag.AddEdge("queue1", "queue2")
|
dag.AddEdge("queue1", "queue2")
|
||||||
dag.AddLoop("queue1", "queue2") // This adds a loop between queue1 and queue2
|
dag.AddLoop("queue2", "queue3") // Add loop to handle array
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
finalResult := dag.Send([]byte(`{}`)) // sending empty payload to initiate
|
finalResult := dag.Send([]byte(`[{"user_id": 1}, {"user_id": 2}]`))
|
||||||
log.Printf("Final result received: %s", string(finalResult.Payload))
|
log.Printf("Final result received: %s", string(finalResult.Payload))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -110,46 +119,32 @@ func (d *DAG) PublishTask(ctx context.Context, payload []byte, queueName string,
|
|||||||
// TaskCallback is called when a task completes and decides the next step
|
// TaskCallback is called when a task completes and decides the next step
|
||||||
func (d *DAG) TaskCallback(ctx context.Context, task *mq.Task) error {
|
func (d *DAG) TaskCallback(ctx context.Context, task *mq.Task) error {
|
||||||
log.Printf("Callback from queue %s with result: %s", task.CurrentQueue, string(task.Result))
|
log.Printf("Callback from queue %s with result: %s", task.CurrentQueue, string(task.Result))
|
||||||
|
|
||||||
// Check if this task belongs to a loop
|
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
loopCtx, isLoopTask := d.loopTaskMap[task.ID]
|
loopCtx, isLoopTask := d.loopTaskMap[task.ID]
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
if isLoopTask {
|
if isLoopTask {
|
||||||
// Send the sub-task result to the loop's result channel
|
|
||||||
loopCtx.subResultCh <- mq.Result{Payload: task.Result, MessageID: task.ID}
|
loopCtx.subResultCh <- mq.Result{Payload: task.Result, MessageID: task.ID}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle loopEdges first, if applicable
|
|
||||||
if loopNode, exists := d.loopEdges[task.CurrentQueue]; exists {
|
if loopNode, exists := d.loopEdges[task.CurrentQueue]; exists {
|
||||||
// This is a loop node, and we need to handle array processing
|
|
||||||
var items []json.RawMessage
|
var items []json.RawMessage
|
||||||
if err := json.Unmarshal(task.Result, &items); err != nil {
|
if err := json.Unmarshal(task.Result, &items); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a loop task context to track the state of this loop
|
|
||||||
loopCtx := &loopTaskContext{
|
loopCtx := &loopTaskContext{
|
||||||
subResultCh: make(chan mq.Result, len(items)), // A channel to collect sub-task results
|
subResultCh: make(chan mq.Result, len(items)), // A channel to collect sub-task results
|
||||||
totalItems: len(items),
|
totalItems: len(items),
|
||||||
results: make([]json.RawMessage, 0, len(items)),
|
results: make([]json.RawMessage, 0, len(items)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the loop context for this task
|
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
d.loopTaskMap[task.ID] = loopCtx
|
d.loopTaskMap[task.ID] = loopCtx
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
|
|
||||||
// Publish a sub-task for each item in the array
|
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
_, err := d.PublishTask(ctx, item, loopNode, task.ID)
|
_, err := d.PublishTask(ctx, item, loopNode, task.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go d.waitForLoopCompletion(ctx, task.ID, task.CurrentQueue)
|
go d.waitForLoopCompletion(ctx, task.ID, task.CurrentQueue)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user