feat: add task completion

This commit is contained in:
sujit
2024-11-18 11:17:25 +05:45
parent e07b8ed3fd
commit 78b266ac04
2 changed files with 26 additions and 33 deletions

View File

@@ -10,14 +10,16 @@ import (
"time" "time"
"golang.org/x/exp/maps" "golang.org/x/exp/maps"
"github.com/oarkflow/mq/storage"
"github.com/oarkflow/mq/storage/memory"
) )
type DAG struct { type DAG struct {
Nodes map[string]*Node Nodes map[string]*Node
Edges map[string][]string Edges map[string][]string
ParentNodes map[string]string ParentNodes map[string]string
taskManager map[string]*TaskManager taskManager storage.IMap[string, *TaskManager]
mu sync.Mutex
finalResult func(taskID string, result Result) finalResult func(taskID string, result Result)
} }
@@ -26,20 +28,16 @@ func NewDAG(finalResultCallback func(taskID string, result Result)) *DAG {
Nodes: make(map[string]*Node), Nodes: make(map[string]*Node),
Edges: make(map[string][]string), Edges: make(map[string][]string),
ParentNodes: make(map[string]string), ParentNodes: make(map[string]string),
taskManager: make(map[string]*TaskManager), taskManager: memory.New[string, *TaskManager](),
finalResult: finalResultCallback, finalResult: finalResultCallback,
} }
} }
func (tm *DAG) AddNode(nodeID string, handler func(payload json.RawMessage) Result) { func (tm *DAG) AddNode(nodeID string, handler func(payload json.RawMessage) Result) {
tm.mu.Lock()
defer tm.mu.Unlock()
tm.Nodes[nodeID] = &Node{ID: nodeID, Handler: handler} tm.Nodes[nodeID] = &Node{ID: nodeID, Handler: handler}
} }
func (tm *DAG) AddEdge(from string, to ...string) { func (tm *DAG) AddEdge(from string, to ...string) {
tm.mu.Lock()
defer tm.mu.Unlock()
tm.Edges[from] = append(tm.Edges[from], to...) tm.Edges[from] = append(tm.Edges[from], to...)
for _, targetNode := range to { for _, targetNode := range to {
tm.ParentNodes[targetNode] = from tm.ParentNodes[targetNode] = from
@@ -253,9 +251,7 @@ func (tm *DAG) formHandler(w http.ResponseWriter, r *http.Request) {
gender := r.FormValue("gender") gender := r.FormValue("gender")
taskID := generateTaskID() taskID := generateTaskID()
manager := NewTaskManager(tm) manager := NewTaskManager(tm)
tm.mu.Lock() tm.taskManager.Set(taskID, manager)
tm.taskManager[taskID] = manager
tm.mu.Unlock()
go manager.Run() go manager.Run()
payload := fmt.Sprintf(`{"email": "%s", "age": "%s", "gender": "%s"}`, email, age, gender) payload := fmt.Sprintf(`{"email": "%s", "age": "%s", "gender": "%s"}`, email, age, gender)
manager.Trigger(taskID, "NodeA", json.RawMessage(payload)) manager.Trigger(taskID, "NodeA", json.RawMessage(payload))
@@ -270,14 +266,12 @@ func (tm *DAG) resultHandler(w http.ResponseWriter, r *http.Request) {
func (tm *DAG) taskStatusHandler(w http.ResponseWriter, r *http.Request) { func (tm *DAG) taskStatusHandler(w http.ResponseWriter, r *http.Request) {
taskID := r.URL.Query().Get("taskID") taskID := r.URL.Query().Get("taskID")
if taskID == "" { if taskID == "" {
http.Error(w, "taskID is missing", http.StatusBadRequest) http.Error(w, `{"message": "taskID is missing"}`, http.StatusBadRequest)
return return
} }
tm.mu.Lock() manager, ok := tm.taskManager.Get(taskID)
manager, ok := tm.taskManager[taskID]
tm.mu.Unlock()
if !ok { if !ok {
http.Error(w, "Invalid taskID", http.StatusNotFound) http.Error(w, `{"message": "Invalid TaskID"}`, http.StatusNotFound)
return return
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View File

@@ -99,12 +99,14 @@
fetch(`/task-result?taskID=${taskID}`) fetch(`/task-result?taskID=${taskID}`)
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
const container = document.getElementById('result'); if(data?.message) {
let htmlContent = ''; document.getElementById('result').innerHTML = `
<p>Error loading task result. ${data.message}</p> <br> <a href="/form">Go back</a>`;
// Show final result in a table } else {
htmlContent += ` const container = document.getElementById('result');
<h2>Final Task Result</h2> let htmlContent = '';
htmlContent += `
<h2>Final Task Result <a href="/form">Go back</a></h2>
<table> <table>
<tr> <tr>
<th>Task ID</th> <th>Task ID</th>
@@ -120,9 +122,7 @@
</tr> </tr>
</table> </table>
`; `;
htmlContent += `
// Show result per node
htmlContent += `
<div class="node-result"> <div class="node-result">
<h2>Result Per Node</h2> <h2>Result Per Node</h2>
<table> <table>
@@ -133,12 +133,10 @@
<th>Node Result Data</th> <th>Node Result Data</th>
</tr> </tr>
`; `;
for (const nodeID in data) {
// Loop through each node result and display in a table if (nodeID !== "Result") {
for (const nodeID in data) { const node = data[nodeID];
if (nodeID !== "Result") { htmlContent += `
const node = data[nodeID];
htmlContent += `
<tr> <tr>
<td>${node.NodeID}</td> <td>${node.NodeID}</td>
<td class="${getStatusClass(node.Status)}">${node.Status}</td> <td class="${getStatusClass(node.Status)}">${node.Status}</td>
@@ -146,13 +144,14 @@
<td><pre>${JSON.stringify(node.Result.Data, null, 2)}</pre></td> <td><pre>${JSON.stringify(node.Result.Data, null, 2)}</pre></td>
</tr> </tr>
`; `;
}
} }
htmlContent += '</table></div>';
container.innerHTML = htmlContent;
} }
htmlContent += '</table></div>';
container.innerHTML = htmlContent;
}) })
.catch(error => { .catch(error => {
console.log(error)
document.getElementById('result').innerHTML = '<p>Error loading task result.</p>'; document.getElementById('result').innerHTML = '<p>Error loading task result.</p>';
}); });
} else { } else {