#223: Added subflow tracking features
This commit is contained in:
@@ -8,6 +8,7 @@ import logging
|
|||||||
import requests
|
import requests
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import http.client
|
import http.client
|
||||||
|
import urllib3
|
||||||
|
|
||||||
class AppBase:
|
class AppBase:
|
||||||
__version__ = None
|
__version__ = None
|
||||||
@@ -66,7 +67,7 @@ class AppBase:
|
|||||||
self.logger.info(ret.text)
|
self.logger.info(ret.text)
|
||||||
except requests.exceptions.ConnectionError as e:
|
except requests.exceptions.ConnectionError as e:
|
||||||
#self.logger.exception("ConnectionError: %s" % e)
|
#self.logger.exception("ConnectionError: %s" % e)
|
||||||
self.logger.exception("Expected ConnectionError happened")
|
self.logger.info("Expected ConnectionError happened")
|
||||||
return
|
return
|
||||||
except TypeError as e:
|
except TypeError as e:
|
||||||
#self.logger.exception(e)
|
#self.logger.exception(e)
|
||||||
@@ -78,7 +79,10 @@ class AppBase:
|
|||||||
if ret.status_code != 200:
|
if ret.status_code != 200:
|
||||||
self.logger.info(ret.text)
|
self.logger.info(ret.text)
|
||||||
except http.client.RemoteDisconnected as e:
|
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
|
return
|
||||||
|
|
||||||
async def cartesian_product(self, L):
|
async def cartesian_product(self, L):
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ type WorkflowExecution struct {
|
|||||||
ExecutionArgument string `json:"execution_argument" datastore:"execution_argument,noindex"`
|
ExecutionArgument string `json:"execution_argument" datastore:"execution_argument,noindex"`
|
||||||
ExecutionId string `json:"execution_id" datastore:"execution_id"`
|
ExecutionId string `json:"execution_id" datastore:"execution_id"`
|
||||||
ExecutionSource string `json:"execution_source" datastore:"execution_source"`
|
ExecutionSource string `json:"execution_source" datastore:"execution_source"`
|
||||||
|
ExecutionParent string `json:"execution_parent" datastore:"execution_parent"`
|
||||||
ExecutionOrg string `json:"execution_org" datastore:"execution_org"`
|
ExecutionOrg string `json:"execution_org" datastore:"execution_org"`
|
||||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||||
LastNode string `json:"last_node" datastore:"last_node"`
|
LastNode string `json:"last_node" datastore:"last_node"`
|
||||||
@@ -2410,7 +2411,7 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) {
|
|||||||
workflow.Actions = newActions
|
workflow.Actions = newActions
|
||||||
newTriggers := []Trigger{}
|
newTriggers := []Trigger{}
|
||||||
for _, trigger := range workflow.Triggers {
|
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
|
// Check if it's actually running
|
||||||
// FIXME: Do this for other triggers too
|
// 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.
|
// This one doesn't really matter.
|
||||||
log.Printf("[INFO] Running POST execution with body of length %d", len(string(body)))
|
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 {
|
if len(string(body)) < 50 {
|
||||||
//log.Println(body)
|
//log.Println(body)
|
||||||
// String in string
|
// String in string
|
||||||
|
|||||||
@@ -5175,7 +5175,7 @@ const AngularWorkflow = (props) => {
|
|||||||
})}
|
})}
|
||||||
</Select>
|
</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
|
<Select
|
||||||
value={subworkflowStartnode}
|
value={subworkflowStartnode}
|
||||||
SelectDisplayProps={{
|
SelectDisplayProps={{
|
||||||
@@ -5208,8 +5208,8 @@ const AngularWorkflow = (props) => {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</Select>
|
</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={{marginTop: "20px", marginBottom: "7px", display: "flex"}}>
|
||||||
<div style={{width: "17px", height: "17px", borderRadius: 17 / 2, backgroundColor: "#f85a3e", marginRight: "10px"}}/>
|
<div style={{width: "17px", height: "17px", borderRadius: 17 / 2, backgroundColor: "#f85a3e", marginRight: "10px"}}/>
|
||||||
<div style={{flex: "10"}}>
|
<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}} />
|
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 (
|
return (
|
||||||
<img alt={execution.execution_source} src={defaultImage} style={{width: size, height: size}} />
|
<img alt={execution.execution_source} src={defaultImage} style={{width: size, height: size}} />
|
||||||
@@ -6564,7 +6567,7 @@ const AngularWorkflow = (props) => {
|
|||||||
</h2>
|
</h2>
|
||||||
</span>
|
</span>
|
||||||
</Breadcrumbs>
|
</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"}}>
|
<div style={{display: "flex"}}>
|
||||||
<h2>Executing Workflow</h2>
|
<h2>Executing Workflow</h2>
|
||||||
<Tooltip color="primary" title="Rerun workflow" placement="top">
|
<Tooltip color="primary" title="Rerun workflow" placement="top">
|
||||||
@@ -6580,19 +6583,23 @@ const AngularWorkflow = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
{executionData.status !== undefined && executionData.status.length > 0 ?
|
{executionData.status !== undefined && executionData.status.length > 0 ?
|
||||||
<div>
|
<div>
|
||||||
<b>Status: </b>{executionData.status}
|
<b>Status: </b>{executionData.status}
|
||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
{executionData.execution_source !== undefined && executionData.execution_source !== null && executionData.execution_source.length > 0 && executionData.execution_source !== "default" ?
|
{executionData.execution_source !== undefined && executionData.execution_source !== null && executionData.execution_source.length > 0 && executionData.execution_source !== "default" ?
|
||||||
<div>
|
<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>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
{executionData.started_at !== undefined ?
|
{executionData.started_at !== undefined ?
|
||||||
<div>
|
<div>
|
||||||
<b>Started: </b>{new Date(executionData.started_at*1000).toISOString()}
|
<b>Started: </b>{new Date(executionData.started_at*1000).toISOString()}
|
||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
@@ -6602,10 +6609,11 @@ const AngularWorkflow = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
<div style={{marginTop: 10}}/>
|
||||||
{executionData.execution_argument !== undefined && executionData.execution_argument.length > 0 ?
|
{executionData.execution_argument !== undefined && executionData.execution_argument.length > 0 ?
|
||||||
parsedExecutionArgument()
|
parsedExecutionArgument()
|
||||||
: null }
|
: 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") ?
|
{executionData.results !== undefined && executionData.results !== null && executionData.results.length > 1 && executionData.results.find(result => result.status === "SKIPPED" || result.status === "FAILURE") ?
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
style={{color: "white", marginBottom: 10, }}
|
style={{color: "white", marginBottom: 10, }}
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ func initializeImages() {
|
|||||||
log.Printf("[WARNING] SHUFFLE_APP_SDK_VERSION not defined. Defaulting to %s", appSdkVersion)
|
log.Printf("[WARNING] SHUFFLE_APP_SDK_VERSION not defined. Defaulting to %s", appSdkVersion)
|
||||||
}
|
}
|
||||||
if workerVersion == "" {
|
if workerVersion == "" {
|
||||||
workerVersion = "0.8.56"
|
workerVersion = "0.8.57"
|
||||||
log.Printf("[WARNING] SHUFFLE_WORKER_VERSION not defined. Defaulting to %s", workerVersion)
|
log.Printf("[WARNING] SHUFFLE_WORKER_VERSION not defined. Defaulting to %s", workerVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
NAME=shuffle-worker
|
NAME=shuffle-worker
|
||||||
VERSION=0.8.56
|
VERSION=0.8.57
|
||||||
|
|
||||||
echo "Running docker build with $NAME:$VERSION"
|
echo "Running docker build with $NAME:$VERSION"
|
||||||
#CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o worker.bin .
|
#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"`
|
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 WorkflowExecution struct {
|
||||||
Type string `json:"type" datastore:"type"`
|
Type string `json:"type" datastore:"type"`
|
||||||
Status string `json:"status" datastore:"status"`
|
Status string `json:"status" datastore:"status"`
|
||||||
@@ -580,6 +578,7 @@ type WorkflowExecution struct {
|
|||||||
ExecutionArgument string `json:"execution_argument" datastore:"execution_argument,noindex"`
|
ExecutionArgument string `json:"execution_argument" datastore:"execution_argument,noindex"`
|
||||||
ExecutionId string `json:"execution_id" datastore:"execution_id"`
|
ExecutionId string `json:"execution_id" datastore:"execution_id"`
|
||||||
ExecutionSource string `json:"execution_source" datastore:"execution_source"`
|
ExecutionSource string `json:"execution_source" datastore:"execution_source"`
|
||||||
|
ExecutionParent string `json:"execution_parent" datastore:"execution_parent"`
|
||||||
ExecutionOrg string `json:"execution_org" datastore:"execution_org"`
|
ExecutionOrg string `json:"execution_org" datastore:"execution_org"`
|
||||||
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
WorkflowId string `json:"workflow_id" datastore:"workflow_id"`
|
||||||
LastNode string `json:"last_node" datastore:"last_node"`
|
LastNode string `json:"last_node" datastore:"last_node"`
|
||||||
@@ -599,6 +598,7 @@ type WorkflowExecution struct {
|
|||||||
} `json:"execution_variables,omitempty" datastore:"execution_variables,omitempty"`
|
} `json:"execution_variables,omitempty" datastore:"execution_variables,omitempty"`
|
||||||
OrgId string `json:"org_id" datastore:"org_id"`
|
OrgId string `json:"org_id" datastore:"org_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Action struct {
|
type Action struct {
|
||||||
AppName string `json:"app_name,omitempty" datastore:"app_name"`
|
AppName string `json:"app_name,omitempty" datastore:"app_name"`
|
||||||
AppVersion string `json:"app_version,omitempty" datastore:"app_version"`
|
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{}
|
action.Parameters = []WorkflowAppActionParameter{}
|
||||||
for _, parameter := range trigger.Parameters {
|
for _, parameter := range trigger.Parameters {
|
||||||
parameter.Variant = "STATIC_VALUE"
|
parameter.Variant = "STATIC_VALUE"
|
||||||
action.Parameters = append(action.Parameters, parameter)
|
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 = ""
|
//trigger.LargeImage = ""
|
||||||
//err = handleSubworkflowExecution(client, workflowExecution, trigger, action)
|
//err = handleSubworkflowExecution(client, workflowExecution, trigger, action)
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user