#223: Added subflow tracking features

This commit is contained in:
frikky
2021-02-19 18:43:22 +01:00
parent 5b7f782e59
commit f663969d58
6 changed files with 65 additions and 19 deletions
+6 -2
View File
@@ -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):
+28 -5
View File
@@ -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
+16 -8
View File
@@ -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: &nbsp;&nbsp;</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: &nbsp;&nbsp;</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: &nbsp;</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, }}
+1 -1
View File
@@ -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 -1
View File
@@ -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 .
+13 -2
View File
@@ -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 {