#223: Added subflow tracking features
This commit is contained in:
@@ -8,6 +8,7 @@ import logging
|
||||
import requests
|
||||
import urllib.parse
|
||||
import http.client
|
||||
import urllib3
|
||||
|
||||
class AppBase:
|
||||
__version__ = None
|
||||
@@ -66,7 +67,7 @@ class AppBase:
|
||||
self.logger.info(ret.text)
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
#self.logger.exception("ConnectionError: %s" % e)
|
||||
self.logger.exception("Expected ConnectionError happened")
|
||||
self.logger.info("Expected ConnectionError happened")
|
||||
return
|
||||
except TypeError as e:
|
||||
#self.logger.exception(e)
|
||||
@@ -78,7 +79,10 @@ class AppBase:
|
||||
if ret.status_code != 200:
|
||||
self.logger.info(ret.text)
|
||||
except http.client.RemoteDisconnected as e:
|
||||
self.logger.exception("Expected Remotedisconnect happened")
|
||||
self.logger.info("Expected Remotedisconnect happened")
|
||||
return
|
||||
except urllib3.exceptions.ProtocolError as e:
|
||||
self.logger.info("Expected ProtocolError happened")
|
||||
return
|
||||
|
||||
async def cartesian_product(self, L):
|
||||
|
||||
@@ -270,6 +270,7 @@ type WorkflowExecution struct {
|
||||
ExecutionArgument string `json:"execution_argument" datastore:"execution_argument,noindex"`
|
||||
ExecutionId string `json:"execution_id" datastore:"execution_id"`
|
||||
ExecutionSource string `json:"execution_source" datastore:"execution_source"`
|
||||
ExecutionParent string `json:"execution_parent" datastore:"execution_parent"`
|
||||
ExecutionOrg string `json:"execution_org" datastore:"execution_org"`
|
||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||
LastNode string `json:"last_node" datastore:"last_node"`
|
||||
@@ -2410,7 +2411,7 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
||||
workflow.Actions = newActions
|
||||
newTriggers := []Trigger{}
|
||||
for _, trigger := range workflow.Triggers {
|
||||
log.Printf("Trigger %s: %s", trigger.TriggerType, trigger.Status)
|
||||
log.Printf("[INFO] Trigger %s: %s", trigger.TriggerType, trigger.Status)
|
||||
|
||||
// Check if it's actually running
|
||||
// FIXME: Do this for other triggers too
|
||||
@@ -3135,12 +3136,34 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf
|
||||
|
||||
// This one doesn't really matter.
|
||||
log.Printf("[INFO] Running POST execution with body of length %d", len(string(body)))
|
||||
if body[0] == 34 && body[len(body)-1] == 34 {
|
||||
body = body[1 : len(body)-1]
|
||||
|
||||
if len(body) >= 4 {
|
||||
if body[0] == 34 && body[len(body)-1] == 34 {
|
||||
body = body[1 : len(body)-1]
|
||||
}
|
||||
if body[0] == 34 && body[len(body)-1] == 34 {
|
||||
body = body[1 : len(body)-1]
|
||||
}
|
||||
}
|
||||
if body[0] == 34 && body[len(body)-1] == 34 {
|
||||
body = body[1 : len(body)-1]
|
||||
|
||||
//workflowExecution.ExecutionSource = "default"
|
||||
sourceWorkflow, sourceWorkflowOk := request.URL.Query()["source_workflow"]
|
||||
if sourceWorkflowOk {
|
||||
//log.Printf("Got source workflow %s", sourceWorkflow)
|
||||
workflowExecution.ExecutionSource = sourceWorkflow[0]
|
||||
} else {
|
||||
//log.Printf("Did NOT get source workflow")
|
||||
|
||||
}
|
||||
|
||||
sourceExecution, sourceExecutionOk := request.URL.Query()["source_execution"]
|
||||
if sourceExecutionOk {
|
||||
log.Printf("Got source execution%s", sourceExecution)
|
||||
workflowExecution.ExecutionParent = sourceExecution[0]
|
||||
} else {
|
||||
//log.Printf("Did NOT get source execution")
|
||||
}
|
||||
|
||||
if len(string(body)) < 50 {
|
||||
//log.Println(body)
|
||||
// String in string
|
||||
|
||||
@@ -5175,7 +5175,7 @@ const AngularWorkflow = (props) => {
|
||||
})}
|
||||
</Select>
|
||||
}
|
||||
{/*subworkflow === undefined || subworkflow === null || subworkflow.id === undefined || subworkflow.actions === null || subworkflow.actions === undefined || subworkflow.actions.length === 0 ? null :
|
||||
{subworkflow === undefined || subworkflow === null || subworkflow.id === undefined || subworkflow.actions === null || subworkflow.actions === undefined || subworkflow.actions.length === 0 ? null :
|
||||
<Select
|
||||
value={subworkflowStartnode}
|
||||
SelectDisplayProps={{
|
||||
@@ -5208,8 +5208,8 @@ const AngularWorkflow = (props) => {
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
*/}
|
||||
{workflow.triggers[selectedTriggerIndex].parameters[0].value.length === 0 ? null : <span style={{marginTop: 5}}><a href={`/workflows/${workflow.triggers[selectedTriggerIndex].parameters[0].value}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>Explore selected workflow</a></span>}
|
||||
}
|
||||
{workflow.triggers[selectedTriggerIndex].parameters[0].value.length === 0 ? null : <span style={{marginTop: 5}}><a href={`/workflows/${workflow.triggers[selectedTriggerIndex].parameters[0].value}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e", marginLeft: 5,}}>Explore selected workflow</a></span>}
|
||||
<div style={{marginTop: "20px", marginBottom: "7px", display: "flex"}}>
|
||||
<div style={{width: "17px", height: "17px", borderRadius: 17 / 2, backgroundColor: "#f85a3e", marginRight: "10px"}}/>
|
||||
<div style={{flex: "10"}}>
|
||||
@@ -6400,6 +6400,9 @@ const AngularWorkflow = (props) => {
|
||||
return <img alt={"email"} src={triggers.find(trigger => trigger.trigger_type === "EMAIL").large_image} style={{width: size, height: size}} />
|
||||
}
|
||||
|
||||
if (execution.execution_parent !== null && execution.execution_parent !== undefined && execution.execution_parent.length > 0) {
|
||||
return <img alt={"parent workflow"} src={triggers.find(trigger => trigger.trigger_type === "SUBFLOW").large_image} style={{width: size, height: size}} />
|
||||
}
|
||||
|
||||
return (
|
||||
<img alt={execution.execution_source} src={defaultImage} style={{width: size, height: size}} />
|
||||
@@ -6564,7 +6567,7 @@ const AngularWorkflow = (props) => {
|
||||
</h2>
|
||||
</span>
|
||||
</Breadcrumbs>
|
||||
<Divider style={{backgroundColor: "white", marginTop: 10, marginBottom: 10,}}/>
|
||||
<Divider style={{backgroundColor: "rgba(255,255,255,0.6)", marginTop: 10, marginBottom: 10,}}/>
|
||||
<div style={{display: "flex"}}>
|
||||
<h2>Executing Workflow</h2>
|
||||
<Tooltip color="primary" title="Rerun workflow" placement="top">
|
||||
@@ -6580,19 +6583,23 @@ const AngularWorkflow = (props) => {
|
||||
</div>
|
||||
{executionData.status !== undefined && executionData.status.length > 0 ?
|
||||
<div>
|
||||
<b>Status: </b>{executionData.status}
|
||||
<b>Status: </b>{executionData.status}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
{executionData.execution_source !== undefined && executionData.execution_source !== null && executionData.execution_source.length > 0 && executionData.execution_source !== "default" ?
|
||||
<div>
|
||||
<b>Source: </b>{executionData.execution_source}
|
||||
<b>Source: </b>{executionData.execution_parent !== null && executionData.execution_parent !== undefined && executionData.execution_parent.length > 0 ?
|
||||
<a href={`/workflows/${executionData.execution_source}?view=executions&execution_id=${executionData.execution_parent}`} target="_blank" style={{textDecoration: "none", color: "#f85a3e"}}>Parent Workflow</a>
|
||||
:
|
||||
executionData.execution_source
|
||||
}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
{executionData.started_at !== undefined ?
|
||||
<div>
|
||||
<b>Started: </b>{new Date(executionData.started_at*1000).toISOString()}
|
||||
<b>Started: </b>{new Date(executionData.started_at*1000).toISOString()}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
@@ -6602,10 +6609,11 @@ const AngularWorkflow = (props) => {
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
<div style={{marginTop: 10}}/>
|
||||
{executionData.execution_argument !== undefined && executionData.execution_argument.length > 0 ?
|
||||
parsedExecutionArgument()
|
||||
: null }
|
||||
<Divider style={{backgroundColor: "white", marginTop: 30, marginBottom: 30,}}/>
|
||||
<Divider style={{backgroundColor: "rgba(255,255,255,0.6)", marginTop: 15, marginBottom: 30,}}/>
|
||||
{executionData.results !== undefined && executionData.results !== null && executionData.results.length > 1 && executionData.results.find(result => result.status === "SKIPPED" || result.status === "FAILURE") ?
|
||||
<FormControlLabel
|
||||
style={{color: "white", marginBottom: 10, }}
|
||||
|
||||
@@ -257,7 +257,7 @@ func initializeImages() {
|
||||
log.Printf("[WARNING] SHUFFLE_APP_SDK_VERSION not defined. Defaulting to %s", appSdkVersion)
|
||||
}
|
||||
if workerVersion == "" {
|
||||
workerVersion = "0.8.56"
|
||||
workerVersion = "0.8.57"
|
||||
log.Printf("[WARNING] SHUFFLE_WORKER_VERSION not defined. Defaulting to %s", workerVersion)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
NAME=shuffle-worker
|
||||
VERSION=0.8.56
|
||||
VERSION=0.8.57
|
||||
|
||||
echo "Running docker build with $NAME:$VERSION"
|
||||
#CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker.bin .
|
||||
|
||||
@@ -571,8 +571,6 @@ type WorkflowAppAction struct {
|
||||
AuthNotRequired bool `json:"auth_not_required" datastore:"auth_not_required" yaml:"auth_not_required"`
|
||||
}
|
||||
|
||||
// FIXME: Generate a callback authentication ID?
|
||||
// FIXME: Add org check ..
|
||||
type WorkflowExecution struct {
|
||||
Type string `json:"type" datastore:"type"`
|
||||
Status string `json:"status" datastore:"status"`
|
||||
@@ -580,6 +578,7 @@ type WorkflowExecution struct {
|
||||
ExecutionArgument string `json:"execution_argument" datastore:"execution_argument,noindex"`
|
||||
ExecutionId string `json:"execution_id" datastore:"execution_id"`
|
||||
ExecutionSource string `json:"execution_source" datastore:"execution_source"`
|
||||
ExecutionParent string `json:"execution_parent" datastore:"execution_parent"`
|
||||
ExecutionOrg string `json:"execution_org" datastore:"execution_org"`
|
||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||
LastNode string `json:"last_node" datastore:"last_node"`
|
||||
@@ -599,6 +598,7 @@ type WorkflowExecution struct {
|
||||
} `json:"execution_variables,omitempty" datastore:"execution_variables,omitempty"`
|
||||
OrgId string `json:"org_id" datastore:"org_id"`
|
||||
}
|
||||
|
||||
type Action struct {
|
||||
AppName string `json:"app_name,omitempty" datastore:"app_name"`
|
||||
AppVersion string `json:"app_version,omitempty" datastore:"app_version"`
|
||||
@@ -1273,12 +1273,23 @@ func handleExecutionResult(workflowExecution WorkflowExecution) {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Add startnode from frontend
|
||||
action.Parameters = []WorkflowAppActionParameter{}
|
||||
for _, parameter := range trigger.Parameters {
|
||||
parameter.Variant = "STATIC_VALUE"
|
||||
action.Parameters = append(action.Parameters, parameter)
|
||||
}
|
||||
|
||||
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
|
||||
Name: "source_workflow",
|
||||
Value: workflowExecution.Workflow.ID,
|
||||
})
|
||||
|
||||
action.Parameters = append(action.Parameters, WorkflowAppActionParameter{
|
||||
Name: "source_execution",
|
||||
Value: workflowExecution.ExecutionId,
|
||||
})
|
||||
|
||||
//trigger.LargeImage = ""
|
||||
//err = handleSubworkflowExecution(client, workflowExecution, trigger, action)
|
||||
//if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user