func NewWorkflow(js []byte) (*Workflow, error) { //g := flow.ParseJSON(js) g, err := flow.ParseJSON(js) if err != nil { return nil, err } wf := &Workflow{ Graph: *g, } for _, port := range wf.GetUnboundInPorts() { wf.InPorts = append(wf.InPorts, port) wf.Graph.MapInPort(fmt.Sprintf("%s.%s", port.Proc, port.Port), port.Proc, port.Port) } for _, port := range wf.GetUnboundOutPorts() { wf.OutPorts = append(wf.OutPorts, port) wf.Graph.MapOutPort(fmt.Sprintf("%s.%s", port.Proc, port.Port), port.Proc, port.Port) } return wf, nil }
// Runs the component graph with json input and producing json output func Run(js []byte, dec *json.Decoder, enc *json.Encoder, errChan chan<- error) <-chan int { done := make(chan int) graph, err := flow.ParseJSON(js) if err != nil { errChan <- err close(errChan) done <- 1 return done } flow.RunNet(graph) for _, port := range graph.GetUnboundOutPorts() { ch := make(chan execute.ThreadParam) graph.SetOutPort(port.Port, ch) go func() { for a := range ch { if err := enc.Encode(&a); err != nil { errChan <- err } } }() } inPortMap := make(map[string]chan execute.ThreadParam) for _, port := range graph.GetUnboundInPorts() { ch := make(chan execute.ThreadParam) inPortMap[port.Port] = ch graph.SetInPort(port.Port, ch) } go func() { for _, ch := range inPortMap { defer close(ch) } for { var p execute.JSONBlock if err := dec.Decode(&p); err != nil { if err != io.EOF { errChan <- err } return } if p.ID == nil { //TODO add error control in JSONBlock unmarshaling?? errChan <- errors.New("No ID") continue } for k, v := range p.Values { tmp := make(map[string]interface{}) tmp[k] = v sthg, err := json.Marshal(&tmp) if err != nil { continue } if _, exists := inPortMap[k]; exists { param := execute.ThreadParam{ Value: execute.JSONValue{Name: k, JSONString: string(sthg)}, ID: *p.ID, Error: *p.Error, } inPortMap[k] <- param } } } }() go func() { <-graph.Wait() close(errChan) done <- 1 }() return done }