mirror of
https://github.com/oarkflow/mq.git
synced 2025-10-29 03:23:36 +08:00
update
This commit is contained in:
@@ -75,3 +75,23 @@ func AvailableDAG() []string {
|
||||
}
|
||||
return op
|
||||
}
|
||||
|
||||
// HasPageNode checks if the DAG contains any Page nodes
|
||||
func (d *DAG) HasPageNode() bool {
|
||||
return d.hasPageNode
|
||||
}
|
||||
|
||||
// ContainsPageNodes iterates through all nodes to check if any are Page nodes
|
||||
// This method provides an alternative way to check for Page nodes by examining
|
||||
// the actual nodes rather than relying on the cached hasPageNode field
|
||||
func (d *DAG) ContainsPageNodes() bool {
|
||||
var hasPage bool
|
||||
d.nodes.ForEach(func(_ string, node *Node) bool {
|
||||
if node.NodeType == Page {
|
||||
hasPage = true
|
||||
return false // Stop iteration when found
|
||||
}
|
||||
return true // Continue iteration
|
||||
})
|
||||
return hasPage
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/oarkflow/json"
|
||||
"github.com/oarkflow/mq"
|
||||
"github.com/oarkflow/mq/dag"
|
||||
)
|
||||
@@ -11,8 +12,24 @@ type OutputHandler struct {
|
||||
dag.Operation
|
||||
}
|
||||
|
||||
func (e *OutputHandler) ProcessTask(ctx context.Context, task *mq.Task) mq.Result {
|
||||
return mq.Result{Payload: task.Payload, Ctx: ctx}
|
||||
func (c *OutputHandler) ProcessTask(ctx context.Context, task *mq.Task) mq.Result {
|
||||
var templateData map[string]any
|
||||
if len(task.Payload) > 0 {
|
||||
if err := json.Unmarshal(task.Payload, &templateData); err != nil {
|
||||
return mq.Result{Payload: task.Payload, Error: err, Ctx: ctx}
|
||||
}
|
||||
}
|
||||
if templateData == nil {
|
||||
templateData = make(map[string]any)
|
||||
}
|
||||
if c.Payload.Mapping != nil {
|
||||
for k, v := range c.Payload.Mapping {
|
||||
_, val := dag.GetVal(ctx, v, templateData)
|
||||
templateData[k] = val
|
||||
}
|
||||
}
|
||||
bt, _ := json.Marshal(templateData)
|
||||
return mq.Result{Payload: bt, Ctx: ctx}
|
||||
}
|
||||
|
||||
func NewOutputHandler(id string) *OutputHandler {
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
},
|
||||
"additional_data": {
|
||||
"conditions": {
|
||||
"default": {
|
||||
"id": "condition:default",
|
||||
"node": "output"
|
||||
},
|
||||
"invalid": {
|
||||
"id": "condition:invalid_login",
|
||||
"node": "error-page",
|
||||
@@ -59,6 +63,15 @@
|
||||
"template_file": "app/templates/error.html"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "output",
|
||||
"node": "output",
|
||||
"data": {
|
||||
"mapping": {
|
||||
"login_message": "eval.{{'Login successful!'}}"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
|
||||
29
services/examples/json/send-email.json
Normal file
29
services/examples/json/send-email.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "Email Notification System",
|
||||
"key": "email:notification",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "Login",
|
||||
"name": "Check Login",
|
||||
"node_key": "login:flow",
|
||||
"first_node": true
|
||||
},
|
||||
{
|
||||
"id": "ContactForm",
|
||||
"node": "render-html",
|
||||
"data": {
|
||||
"additional_data": {
|
||||
"schema_file": "schema.json",
|
||||
"template_file": "app/templates/basic.html"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"edges": [
|
||||
{
|
||||
"source": "Login.output",
|
||||
"label": "on_success",
|
||||
"target": [ "ContactForm" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -12,20 +12,39 @@ import (
|
||||
"github.com/oarkflow/mq/services"
|
||||
)
|
||||
|
||||
func main() {
|
||||
handlerBytes, err := os.ReadFile("json/login.json")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var handler services.Handler
|
||||
err = json.Unmarshal(handlerBytes, &handler)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var availableHandlers = map[string]bool{
|
||||
"json/login.json": false,
|
||||
"json/send-email.json": true,
|
||||
}
|
||||
|
||||
func SetupHandler() (*dag.DAG, error) {
|
||||
var flowToServe *dag.DAG
|
||||
brokerAddr := ":8081"
|
||||
flow := services.SetupHandler(handler, brokerAddr)
|
||||
if flow.Error != nil {
|
||||
fmt.Println("Error setting up handler:", flow.Error)
|
||||
for file, serve := range availableHandlers {
|
||||
handlerBytes, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var handler services.Handler
|
||||
err = json.Unmarshal(handlerBytes, &handler)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
flow := services.SetupHandler(handler, brokerAddr)
|
||||
if flow.Error != nil {
|
||||
return nil, flow.Error
|
||||
}
|
||||
if serve {
|
||||
flowToServe = flow
|
||||
}
|
||||
}
|
||||
return flowToServe, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
flow, err := SetupHandler()
|
||||
if err != nil {
|
||||
fmt.Println("Error setting up handlers:", err)
|
||||
return
|
||||
}
|
||||
flow.Start(context.Background(), ":5000")
|
||||
@@ -34,4 +53,5 @@ func main() {
|
||||
func init() {
|
||||
dag.AddHandler("render-html", func(id string) mq.Processor { return handlers.NewRenderHTMLNode(id) })
|
||||
dag.AddHandler("condition", func(id string) mq.Processor { return handlers.NewCondition(id) })
|
||||
dag.AddHandler("output", func(id string) mq.Processor { return handlers.NewOutputHandler(id) })
|
||||
}
|
||||
|
||||
@@ -41,18 +41,36 @@ func SetupHandler(handler Handler, brokerAddr string, async ...bool) *dag.DAG {
|
||||
if len(async) > 0 {
|
||||
syncMode = async[0]
|
||||
}
|
||||
key := fmt.Sprintf(`%s-%v`, handler.Key, syncMode)
|
||||
key := handler.Key
|
||||
existingDAG := dag.GetDAG(key)
|
||||
if existingDAG != nil {
|
||||
return existingDAG
|
||||
}
|
||||
flow := dag.NewDAG(handler.Name, handler.Key, nil, mq.WithSyncMode(syncMode), mq.WithBrokerURL(brokerAddr))
|
||||
for _, node := range handler.Nodes {
|
||||
err := prepareNode(flow, node)
|
||||
if err != nil {
|
||||
flow.Error = err
|
||||
if node.Node == "" && node.NodeKey == "" {
|
||||
flow.Error = errors.New("Node not defined " + node.ID)
|
||||
return flow
|
||||
}
|
||||
if node.Node != "" {
|
||||
err := prepareNode(flow, node)
|
||||
if err != nil {
|
||||
flow.Error = err
|
||||
return flow
|
||||
}
|
||||
} else if node.NodeKey != "" {
|
||||
newDag := dag.GetDAG(node.NodeKey)
|
||||
if newDag == nil {
|
||||
flow.Error = errors.New("DAG not found " + node.NodeKey)
|
||||
return flow
|
||||
}
|
||||
nodeType := dag.Function
|
||||
if newDag.HasPageNode() {
|
||||
nodeType = dag.Page
|
||||
}
|
||||
fmt.Println(node.Name, node.ID, node.NodeKey, node.FirstNode)
|
||||
flow.AddDAGNode(nodeType, node.Name, node.ID, newDag, node.FirstNode)
|
||||
}
|
||||
}
|
||||
for _, edge := range handler.Edges {
|
||||
if edge.Label == "" {
|
||||
@@ -133,6 +151,8 @@ func prepareNode(flow *dag.DAG, node Node) error {
|
||||
Reverse: cond.FilterGroup.Reverse,
|
||||
Filters: fillers,
|
||||
}
|
||||
} else {
|
||||
conditions[key] = nil
|
||||
}
|
||||
}
|
||||
flow.AddCondition(node.ID, condition)
|
||||
|
||||
@@ -136,6 +136,7 @@ type Data struct {
|
||||
type Node struct {
|
||||
Name string `json:"name,omitempty" yaml:"name,omitempty"`
|
||||
ID string `json:"id" yaml:"id"`
|
||||
NodeKey string `json:"node_key" yaml:"node_key"`
|
||||
Node string `json:"node" yaml:"node"`
|
||||
Data Data `json:"data" yaml:"data"`
|
||||
FirstNode bool `json:"first_node" yaml:"first_node"`
|
||||
|
||||
Reference in New Issue
Block a user