Fixed execution problems for subflows related to multiple executions and missing execution argument
This commit is contained in:
@@ -1488,7 +1488,7 @@ class AppBase:
|
|||||||
# Means it's a single item -> continue
|
# Means it's a single item -> continue
|
||||||
if seconditem == "":
|
if seconditem == "":
|
||||||
print("[INFO] In first - handling %s. Len: %d" % (firstitem, len(basejson)))
|
print("[INFO] In first - handling %s. Len: %d" % (firstitem, len(basejson)))
|
||||||
if firstitem.lower() == "max" or firstitem.lower() == "last":
|
if firstitem.lower() == "max" or firstitem.lower() == "last" or firstitem.lower() == "end":
|
||||||
firstitem = len(basejson)-1
|
firstitem = len(basejson)-1
|
||||||
elif firstitem.lower() == "min" or firstitem.lower() == "first":
|
elif firstitem.lower() == "min" or firstitem.lower() == "first":
|
||||||
firstitem = 0
|
firstitem = 0
|
||||||
@@ -1503,14 +1503,14 @@ class AppBase:
|
|||||||
newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:])
|
newvalue, is_loop = (tmpitem, parsersplit[outercnt+1:])
|
||||||
else:
|
else:
|
||||||
print("[INFO] In ELSE - handling %s and %s" % (firstitem, seconditem))
|
print("[INFO] In ELSE - handling %s and %s" % (firstitem, seconditem))
|
||||||
if firstitem.lower() == "max" or firstitem.lower() == "last":
|
if firstitem.lower() == "max" or firstitem.lower() == "last" or firstitem.lower() == "end":
|
||||||
firstitem = len(basejson)-1
|
firstitem = len(basejson)-1
|
||||||
elif firstitem.lower() == "min" or firstitem.lower() == "first":
|
elif firstitem.lower() == "min" or firstitem.lower() == "first":
|
||||||
firstitem = 0
|
firstitem = 0
|
||||||
else:
|
else:
|
||||||
firstitem = int(firstitem)
|
firstitem = int(firstitem)
|
||||||
|
|
||||||
if seconditem.lower() == "max" or seconditem.lower() == "last":
|
if seconditem.lower() == "max" or seconditem.lower() == "last" or firstitem.lower() == "end":
|
||||||
seconditem = len(basejson)-1
|
seconditem = len(basejson)-1
|
||||||
elif seconditem.lower() == "min" or seconditem.lower() == "first":
|
elif seconditem.lower() == "min" or seconditem.lower() == "first":
|
||||||
seconditem = 0
|
seconditem = 0
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ module main
|
|||||||
|
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared
|
//replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared
|
||||||
|
|
||||||
//replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi
|
//replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi
|
||||||
//replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch
|
//replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch
|
||||||
@@ -22,7 +22,7 @@ require (
|
|||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/h2non/filetype v1.1.1
|
github.com/h2non/filetype v1.1.1
|
||||||
github.com/satori/go.uuid v1.2.0
|
github.com/satori/go.uuid v1.2.0
|
||||||
github.com/shuffle/shuffle-shared v0.1.62
|
github.com/shuffle/shuffle-shared v0.1.70
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
||||||
|
|||||||
@@ -2885,7 +2885,7 @@ func handleSwaggerValidation(body []byte) (shuffle.ParsedOpenApi, error) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isJson = true
|
isJson = true
|
||||||
log.Printf("Successfully parsed JSON!")
|
//log.Printf("[DEBUG] Successfully parsed JSON!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(version.SwaggerVersion) > 0 && len(version.Swagger) == 0 {
|
if len(version.SwaggerVersion) > 0 && len(version.Swagger) == 0 {
|
||||||
|
|||||||
@@ -1040,7 +1040,6 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user, userErr := shuffle.HandleApiAuthentication(resp, request)
|
user, userErr := shuffle.HandleApiAuthentication(resp, request)
|
||||||
|
|
||||||
if user.Role == "org-reader" {
|
if user.Role == "org-reader" {
|
||||||
log.Printf("[WARNING] Org-reader doesn't have access to run workflow: %s (%s)", user.Username, user.Id)
|
log.Printf("[WARNING] Org-reader doesn't have access to run workflow: %s (%s)", user.Username, user.Id)
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
@@ -2171,7 +2170,7 @@ func iterateOpenApiGithub(fs billy.Filesystem, dir []os.FileInfo, extra string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if appCounter > 0 {
|
if appCounter > 0 {
|
||||||
log.Printf("Preloaded %d OpenApi apps in folder %s!", appCounter, extra)
|
//log.Printf("Preloaded %d OpenApi apps in folder %s!", appCounter, extra)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
backend:
|
backend:
|
||||||
#build: ./backend
|
build: ./backend
|
||||||
image: ghcr.io/frikky/shuffle-backend:nightly
|
image: ghcr.io/frikky/shuffle-backend:nightly
|
||||||
container_name: shuffle-backend
|
container_name: shuffle-backend
|
||||||
hostname: ${BACKEND_HOSTNAME}
|
hostname: ${BACKEND_HOSTNAME}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const CodeEditor = (props) => {
|
|||||||
function expectedOutput(input) {
|
function expectedOutput(input) {
|
||||||
|
|
||||||
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
const found = input.match(/[$]{1}([a-zA-Z0-9_-]+\.?){1}([a-zA-Z0-9#_-]+\.?){0,}/g)
|
||||||
console.log(found)
|
//console.log(found)
|
||||||
|
|
||||||
try{
|
try{
|
||||||
// When the found array is empty.
|
// When the found array is empty.
|
||||||
|
|||||||
@@ -1056,7 +1056,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
curworkflowComment.position = cyelements[key].position();
|
curworkflowComment.position = cyelements[key].position();
|
||||||
console.log(curworkflowComment)
|
//console.log(curworkflowComment)
|
||||||
|
|
||||||
newComments.push(curworkflowComment);
|
newComments.push(curworkflowComment);
|
||||||
} else {
|
} else {
|
||||||
@@ -3193,14 +3193,14 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
event.path !== null &&
|
event.path !== null &&
|
||||||
event.path.length > 0
|
event.path.length > 0
|
||||||
) {
|
) {
|
||||||
console.log("PATH: ", event.path[0])
|
//console.log("PATH: ", event.path[0])
|
||||||
if (event.path[0].localName !== "body") {
|
if (event.path[0].localName !== "body") {
|
||||||
//console.log("Skipping because body is not targeted")
|
//console.log("Skipping because body is not targeted")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("PATH2: ", event.target)
|
//console.log("PATH2: ", event.target)
|
||||||
if (
|
if (
|
||||||
event.target !== undefined &&
|
event.target !== undefined &&
|
||||||
event.target !== null
|
event.target !== null
|
||||||
@@ -7643,6 +7643,11 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
|
|
||||||
const handleWorkflowSelectionUpdate = (e) => {
|
const handleWorkflowSelectionUpdate = (e) => {
|
||||||
setUpdate(Math.random());
|
setUpdate(Math.random());
|
||||||
|
|
||||||
|
if (e.target.value === undefined || e.target.value === null || e.target.value.id === undefined) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
workflow.triggers[
|
workflow.triggers[
|
||||||
selectedTriggerIndex
|
selectedTriggerIndex
|
||||||
].parameters[0].value = e.target.value.id;
|
].parameters[0].value = e.target.value.id;
|
||||||
@@ -10268,7 +10273,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>Execution Argument</h3>
|
<h3>Execution Argument</h3>
|
||||||
<div style={{ maxHeight: 200, overflowY: "scroll" }}>
|
<div style={{ maxHeight: 200, overflowY: "auto" }}>
|
||||||
{executionData.execution_argument}
|
{executionData.execution_argument}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -10415,11 +10420,11 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
base = JSON.stringify(base)
|
base = JSON.stringify(base)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_node_name === "execution_argument") {
|
if (base_node_name === "execution_argument" || base_node_name === "Execution Argument") {
|
||||||
base_node_name = "exec"
|
base_node_name = "exec"
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("COPY: ", copy);
|
console.log("COPY: ", base_node_name, copy);
|
||||||
|
|
||||||
//var newitem = JSON.parse(base);
|
//var newitem = JSON.parse(base);
|
||||||
var newitem = validateJson(base).result
|
var newitem = validateJson(base).result
|
||||||
@@ -11352,10 +11357,13 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
: selectedResult.status === "ABORTED" || selectedResult.status === "FAILURE"
|
: selectedResult.status === "ABORTED" || selectedResult.status === "FAILURE"
|
||||||
? "red"
|
? "red"
|
||||||
: yellow;
|
: yellow;
|
||||||
|
|
||||||
const validate = !codeModalOpen
|
const validate = !codeModalOpen
|
||||||
? ""
|
? ""
|
||||||
: validateJson(selectedResult.result.trim());
|
: validateJson(selectedResult.result.trim());
|
||||||
|
|
||||||
if (validate.valid && typeof validate.result === "string") {
|
if (validate.valid && typeof validate.result === "string") {
|
||||||
|
console.log(validate.result)
|
||||||
validate.result = JSON.parse(validate.result);
|
validate.result = JSON.parse(validate.result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11691,7 +11699,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Zoom in={true} timeout={1000} style={{ transitionDelay: `${150}ms` }}>
|
<Fade in={true} timeout={1000} style={{ transitionDelay: `${150}ms` }}>
|
||||||
<CytoscapeComponent
|
<CytoscapeComponent
|
||||||
elements={elements}
|
elements={elements}
|
||||||
minZoom={0.35}
|
minZoom={0.35}
|
||||||
@@ -11714,7 +11722,7 @@ const AngularWorkflow = (defaultprops) => {
|
|||||||
setCy(incy);
|
setCy(incy);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Zoom>
|
</Fade>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{executionModal}
|
{executionModal}
|
||||||
|
|||||||
@@ -429,7 +429,11 @@ export const validateJson = (showResult) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log("VALID: ", jsonvalid, result)
|
if (jsonvalid && typeof result === "number") {
|
||||||
|
jsonvalid = false
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log("VALID: ", jsonvalid, result, typeof result)
|
||||||
return {
|
return {
|
||||||
valid: jsonvalid,
|
valid: jsonvalid,
|
||||||
result: result,
|
result: result,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
NAME=shuffle-worker
|
NAME=shuffle-worker
|
||||||
VERSION=0.9.45
|
VERSION=0.9.46
|
||||||
|
|
||||||
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 .
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ require (
|
|||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/shuffle/shuffle-shared v0.1.60
|
github.com/shuffle/shuffle-shared v0.1.70
|
||||||
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
go4.org v0.0.0-20201209231011-d4a079459e60 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -580,6 +580,8 @@ github.com/shuffle/shuffle-shared v0.1.55 h1:feHtTN7Uhr1aMxkMIo3xZbr97599VB2eLek
|
|||||||
github.com/shuffle/shuffle-shared v0.1.55/go.mod h1:2ndjLm4ZOvY6arGFwOgGnkQ457Ke7gka9HDF/EkdIxQ=
|
github.com/shuffle/shuffle-shared v0.1.55/go.mod h1:2ndjLm4ZOvY6arGFwOgGnkQ457Ke7gka9HDF/EkdIxQ=
|
||||||
github.com/shuffle/shuffle-shared v0.1.60 h1:Jjb6TfE/KnVfCryIL2vtRHBnBX307slVlGBjaEqgwW4=
|
github.com/shuffle/shuffle-shared v0.1.60 h1:Jjb6TfE/KnVfCryIL2vtRHBnBX307slVlGBjaEqgwW4=
|
||||||
github.com/shuffle/shuffle-shared v0.1.60/go.mod h1:2ndjLm4ZOvY6arGFwOgGnkQ457Ke7gka9HDF/EkdIxQ=
|
github.com/shuffle/shuffle-shared v0.1.60/go.mod h1:2ndjLm4ZOvY6arGFwOgGnkQ457Ke7gka9HDF/EkdIxQ=
|
||||||
|
github.com/shuffle/shuffle-shared v0.1.68 h1:xneGx6ZBU9hgIPt3W6pMUIoTZDxNJbOX/cKhndoVu3Y=
|
||||||
|
github.com/shuffle/shuffle-shared v0.1.68/go.mod h1:2ndjLm4ZOvY6arGFwOgGnkQ457Ke7gka9HDF/EkdIxQ=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
|
|||||||
+199
-151
@@ -69,7 +69,7 @@ var nextActions []string
|
|||||||
var extra int
|
var extra int
|
||||||
var startAction string
|
var startAction string
|
||||||
*/
|
*/
|
||||||
var results []shuffle.ActionResult
|
//var results []shuffle.ActionResult
|
||||||
var allLogs map[string]string
|
var allLogs map[string]string
|
||||||
var containerIds []string
|
var containerIds []string
|
||||||
var downloadedImages []string
|
var downloadedImages []string
|
||||||
@@ -660,6 +660,7 @@ func removeIndex(s []string, i int) []string {
|
|||||||
|
|
||||||
func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
startAction, extra, children, parents, visited, executed, nextActions, environments := shuffle.GetExecutionVariables(ctx, workflowExecution.ExecutionId)
|
startAction, extra, children, parents, visited, executed, nextActions, environments := shuffle.GetExecutionVariables(ctx, workflowExecution.ExecutionId)
|
||||||
log.Printf("[DEBUG][%s] Getting info for %s. Extra: %d", workflowExecution.ExecutionId, workflowExecution.ExecutionId, extra)
|
log.Printf("[DEBUG][%s] Getting info for %s. Extra: %d", workflowExecution.ExecutionId, workflowExecution.ExecutionId, extra)
|
||||||
dockercli, err := dockerclient.NewEnvClient()
|
dockercli, err := dockerclient.NewEnvClient()
|
||||||
@@ -840,6 +841,8 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
// SKIP if it's not onprem
|
// SKIP if it's not onprem
|
||||||
toRemove := []int{}
|
toRemove := []int{}
|
||||||
//log.Printf("\n\nNEXTACTIONS: %#v\n\n", nextActions)
|
//log.Printf("\n\nNEXTACTIONS: %#v\n\n", nextActions)
|
||||||
|
// FIXME: In this loop, there may be an ordering issue where a subflow and other triggers don't wait for all parent nodes to finish, due to that happening farther down in the loop. That means they may execute with only a single parent node actually being finishing.
|
||||||
|
// FIXME: Look at how to fix it by moving it farther down. PS: Fixing this, means it should be fixed in the worker too. Make them generic in shuffle mod
|
||||||
for index, nextAction := range nextActions {
|
for index, nextAction := range nextActions {
|
||||||
action := getAction(workflowExecution, nextAction, environment)
|
action := getAction(workflowExecution, nextAction, environment)
|
||||||
// check visited and onprem
|
// check visited and onprem
|
||||||
@@ -854,145 +857,6 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
newExecId := fmt.Sprintf("%s_%s", workflowExecution.ExecutionId, nextAction)
|
|
||||||
if !shuffle.ArrayContains(executedIds, newExecId) {
|
|
||||||
executedIds = append(executedIds, newExecId)
|
|
||||||
toRemove = append(toRemove, index)
|
|
||||||
} else {
|
|
||||||
//log.Printf("\n\n[DEBUG] %s is already executed. Continuing.", newExecId)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// max 1000 :o
|
|
||||||
if len(executedIds) >= 1000 {
|
|
||||||
executedIds = executedIds[900:999]
|
|
||||||
}
|
|
||||||
|
|
||||||
if action.AppName == "Shuffle Tools" && (action.Name == "skip_me" || action.Name == "router" || action.Name == "route") {
|
|
||||||
err := runSkipAction(topClient, action, workflowExecution.Workflow.ID, workflowExecution.ExecutionId, workflowExecution.Authorization, "SKIPPED")
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[DEBUG][%s] Error in skipme for %s: %s", workflowExecution.ExecutionId, action.Label, err)
|
|
||||||
} else {
|
|
||||||
log.Printf("[INFO][%s] Adding visited (4): %s", workflowExecution.ExecutionId, action.Label)
|
|
||||||
|
|
||||||
visited = append(visited, action.ID)
|
|
||||||
executed = append(executed, action.ID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else if action.AppName == "Shuffle Workflow" {
|
|
||||||
//log.Printf("SHUFFLE WORKFLOW: %#v", action)
|
|
||||||
action.Environment = environment
|
|
||||||
action.AppName = "shuffle-subflow"
|
|
||||||
action.Name = "run_subflow"
|
|
||||||
action.AppVersion = "1.0.0"
|
|
||||||
|
|
||||||
//appname := action.AppName
|
|
||||||
//appversion := action.AppVersion
|
|
||||||
//appname = strings.Replace(appname, ".", "-", -1)
|
|
||||||
//appversion = strings.Replace(appversion, ".", "-", -1)
|
|
||||||
// shuffle-subflow_1.0.0
|
|
||||||
|
|
||||||
//visited = append(visited, action.ID)
|
|
||||||
//executed = append(executed, action.ID)
|
|
||||||
|
|
||||||
trigger := shuffle.Trigger{}
|
|
||||||
for _, innertrigger := range workflowExecution.Workflow.Triggers {
|
|
||||||
if innertrigger.ID == action.ID {
|
|
||||||
trigger = innertrigger
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Add startnode from frontend
|
|
||||||
action.Label = trigger.Label
|
|
||||||
action.Parameters = []shuffle.WorkflowAppActionParameter{}
|
|
||||||
for _, parameter := range trigger.Parameters {
|
|
||||||
parameter.Variant = "STATIC_VALUE"
|
|
||||||
action.Parameters = append(action.Parameters, parameter)
|
|
||||||
}
|
|
||||||
|
|
||||||
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
|
||||||
Name: "source_workflow",
|
|
||||||
Value: workflowExecution.Workflow.ID,
|
|
||||||
})
|
|
||||||
|
|
||||||
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
|
||||||
Name: "source_execution",
|
|
||||||
Value: workflowExecution.ExecutionId,
|
|
||||||
})
|
|
||||||
|
|
||||||
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
|
||||||
Name: "source_node",
|
|
||||||
Value: trigger.ID,
|
|
||||||
})
|
|
||||||
|
|
||||||
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
|
||||||
Name: "source_auth",
|
|
||||||
Value: workflowExecution.Authorization,
|
|
||||||
})
|
|
||||||
|
|
||||||
//trigger.LargeImage = ""
|
|
||||||
//err = handleSubworkflowExecution(client, workflowExecution, trigger, action)
|
|
||||||
//if err != nil {
|
|
||||||
// log.Printf("[ERROR] Failed to execute subworkflow: %s", err)
|
|
||||||
//} else {
|
|
||||||
// log.Printf("[INFO] Executed subworkflow!")
|
|
||||||
//}
|
|
||||||
//continue
|
|
||||||
} else if action.AppName == "User Input" {
|
|
||||||
log.Printf("[DEBUG] RUNNING USER INPUT!")
|
|
||||||
|
|
||||||
if action.ID == workflowExecution.Start {
|
|
||||||
log.Printf("[DEBUG] Skipping user input because it's the startnode")
|
|
||||||
visited = append(visited, action.ID)
|
|
||||||
executed = append(executed, action.ID)
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
log.Printf("[DEBUG] Should stop after this iteration because it's user-input based. %#v", action)
|
|
||||||
trigger := shuffle.Trigger{}
|
|
||||||
for _, innertrigger := range workflowExecution.Workflow.Triggers {
|
|
||||||
if innertrigger.ID == action.ID {
|
|
||||||
trigger = innertrigger
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action.Label = action.Label
|
|
||||||
action.Parameters = []shuffle.WorkflowAppActionParameter{}
|
|
||||||
for _, parameter := range trigger.Parameters {
|
|
||||||
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
|
||||||
Name: parameter.Name,
|
|
||||||
Value: parameter.Value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger.LargeImage = ""
|
|
||||||
triggerData, err := json.Marshal(trigger)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[WARNING] Failed unmarshalling action: %s", err)
|
|
||||||
triggerData = []byte("Failed unmarshalling. Cancel execution!")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = runUserInput(topClient, action, workflowExecution.Workflow.ID, workflowExecution, workflowExecution.Authorization, string(triggerData), dockercli)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[ERROR] Failed launching backend magic: %s", err)
|
|
||||||
os.Exit(3)
|
|
||||||
} else {
|
|
||||||
log.Printf("[INFO] Launched user input node succesfully!")
|
|
||||||
os.Exit(3)
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//log.Printf("Handling action %#v", action)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(toRemove) > 0 {
|
|
||||||
//toRemove = []int{}
|
|
||||||
//for index, nextAction := range nextActions {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not really sure how this edgecase happens.
|
// Not really sure how this edgecase happens.
|
||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
@@ -1030,12 +894,7 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
|
|
||||||
if continueOuter {
|
if continueOuter {
|
||||||
log.Printf("[INFO] Parents of %s aren't finished: %s", nextAction, strings.Join(parents[nextAction], ", "))
|
log.Printf("[INFO] Parents of %s aren't finished: %s", nextAction, strings.Join(parents[nextAction], ", "))
|
||||||
//for _, tmpaction := range parents[nextAction] {
|
|
||||||
// action := getAction(workflowExecution, tmpaction)
|
|
||||||
// _ = action
|
|
||||||
// //log.Printf("Parent: %s", action.Label)
|
|
||||||
//}
|
|
||||||
// Find the result of the nodes?
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1043,11 +902,200 @@ func handleExecutionResult(workflowExecution shuffle.WorkflowExecution) {
|
|||||||
actionResult := getResult(workflowExecution, nextAction)
|
actionResult := getResult(workflowExecution, nextAction)
|
||||||
if actionResult.Action.ID == action.ID {
|
if actionResult.Action.ID == action.ID {
|
||||||
log.Printf("[INFO] %s already has status %s.", action.ID, actionResult.Status)
|
log.Printf("[INFO] %s already has status %s.", action.ID, actionResult.Status)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[INFO][%s] %s:%s has no status result yet. Should execute.", workflowExecution.ExecutionId, action.Name, action.ID)
|
log.Printf("[INFO][%s] %s:%s has no status result yet. Should execute.", workflowExecution.ExecutionId, action.Name, action.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newExecId := fmt.Sprintf("%s_%s", workflowExecution.ExecutionId, nextAction)
|
||||||
|
_, err := shuffle.GetCache(ctx, newExecId)
|
||||||
|
if err == nil {
|
||||||
|
//log.Printf("\n\n[DEBUG] Already found %s - returning\n\n", newExecId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheData := []byte("1")
|
||||||
|
err = shuffle.SetCache(ctx, newExecId, cacheData)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[WARNING] Failed setting cache for action %s: %s", newExecId, err)
|
||||||
|
} else {
|
||||||
|
log.Printf("\n\n[DEBUG] Adding %s to cache. Name: %s\n\n", newExecId, action.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if action.AppName == "Shuffle Tools" && (action.Name == "skip_me" || action.Name == "router" || action.Name == "route") {
|
||||||
|
topClient := &http.Client{
|
||||||
|
Timeout: 3 * time.Second,
|
||||||
|
}
|
||||||
|
err := runSkipAction(topClient, action, workflowExecution.Workflow.ID, workflowExecution.ExecutionId, workflowExecution.Authorization, "SKIPPED")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[DEBUG][%s] Error in skipme for %s: %s", workflowExecution.ExecutionId, action.Label, err)
|
||||||
|
} else {
|
||||||
|
log.Printf("[INFO][%s] Adding visited (4): %s", workflowExecution.ExecutionId, action.Label)
|
||||||
|
|
||||||
|
visited = append(visited, action.ID)
|
||||||
|
executed = append(executed, action.ID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if action.AppName == "Shuffle Workflow" {
|
||||||
|
//log.Printf("SHUFFLE WORKFLOW: %#v", action)
|
||||||
|
branchesFound := 0
|
||||||
|
parentFinished := 0
|
||||||
|
|
||||||
|
for _, item := range workflowExecution.Workflow.Branches {
|
||||||
|
if item.DestinationID == action.ID {
|
||||||
|
branchesFound += 1
|
||||||
|
|
||||||
|
for _, result := range workflowExecution.Results {
|
||||||
|
if result.Action.ID == item.SourceID {
|
||||||
|
// Check for fails etc
|
||||||
|
if result.Status == "SUCCESS" || result.Status == "SKIPPED" {
|
||||||
|
parentFinished += 1
|
||||||
|
} else {
|
||||||
|
log.Printf("Parent %s has status %s", result.Action.Label, result.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Should execute %s (?). Branches: %d. Parents done: %d", action.AppName, branchesFound, parentFinished)
|
||||||
|
if branchesFound == parentFinished {
|
||||||
|
action.Environment = environment
|
||||||
|
action.AppName = "shuffle-subflow"
|
||||||
|
action.Name = "run_subflow"
|
||||||
|
action.AppVersion = "1.0.0"
|
||||||
|
|
||||||
|
//appname := action.AppName
|
||||||
|
//appversion := action.AppVersion
|
||||||
|
//appname = strings.Replace(appname, ".", "-", -1)
|
||||||
|
//appversion = strings.Replace(appversion, ".", "-", -1)
|
||||||
|
// shuffle-subflow_1.0.0
|
||||||
|
|
||||||
|
//visited = append(visited, action.ID)
|
||||||
|
//executed = append(executed, action.ID)
|
||||||
|
|
||||||
|
trigger := shuffle.Trigger{}
|
||||||
|
for _, innertrigger := range workflowExecution.Workflow.Triggers {
|
||||||
|
if innertrigger.ID == action.ID {
|
||||||
|
trigger = innertrigger
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Add startnode from frontend
|
||||||
|
action.Label = trigger.Label
|
||||||
|
action.Parameters = []shuffle.WorkflowAppActionParameter{}
|
||||||
|
for _, parameter := range trigger.Parameters {
|
||||||
|
parameter.Variant = "STATIC_VALUE"
|
||||||
|
action.Parameters = append(action.Parameters, parameter)
|
||||||
|
}
|
||||||
|
|
||||||
|
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
||||||
|
Name: "source_workflow",
|
||||||
|
Value: workflowExecution.Workflow.ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
||||||
|
Name: "source_execution",
|
||||||
|
Value: workflowExecution.ExecutionId,
|
||||||
|
})
|
||||||
|
|
||||||
|
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
||||||
|
Name: "source_node",
|
||||||
|
Value: trigger.ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
||||||
|
Name: "source_auth",
|
||||||
|
Value: workflowExecution.Authorization,
|
||||||
|
})
|
||||||
|
|
||||||
|
//trigger.LargeImage = ""
|
||||||
|
//err = handleSubworkflowExecution(client, workflowExecution, trigger, action)
|
||||||
|
//if err != nil {
|
||||||
|
// log.Printf("[ERROR] Failed to execute subworkflow: %s", err)
|
||||||
|
//} else {
|
||||||
|
// log.Printf("[INFO] Executed subworkflow!")
|
||||||
|
//}
|
||||||
|
//continue
|
||||||
|
}
|
||||||
|
} else if action.AppName == "User Input" {
|
||||||
|
log.Printf("[DEBUG] RUNNING USER INPUT!")
|
||||||
|
branchesFound := 0
|
||||||
|
parentFinished := 0
|
||||||
|
|
||||||
|
for _, item := range workflowExecution.Workflow.Branches {
|
||||||
|
if item.DestinationID == action.ID {
|
||||||
|
branchesFound += 1
|
||||||
|
|
||||||
|
for _, result := range workflowExecution.Results {
|
||||||
|
if result.Action.ID == item.SourceID {
|
||||||
|
// Check for fails etc
|
||||||
|
if result.Status == "SUCCESS" || result.Status == "SKIPPED" {
|
||||||
|
parentFinished += 1
|
||||||
|
} else {
|
||||||
|
log.Printf("Parent %s has status %s", result.Action.Label, result.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Should execute %s (?). Branches: %d. Parents done: %d", action.AppName, branchesFound, parentFinished)
|
||||||
|
if branchesFound == parentFinished {
|
||||||
|
|
||||||
|
if action.ID == workflowExecution.Start {
|
||||||
|
log.Printf("[DEBUG] Skipping user input because it's the startnode")
|
||||||
|
visited = append(visited, action.ID)
|
||||||
|
executed = append(executed, action.ID)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] Should stop after this iteration because it's user-input based. %#v", action)
|
||||||
|
trigger := shuffle.Trigger{}
|
||||||
|
for _, innertrigger := range workflowExecution.Workflow.Triggers {
|
||||||
|
if innertrigger.ID == action.ID {
|
||||||
|
trigger = innertrigger
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
action.Label = action.Label
|
||||||
|
action.Parameters = []shuffle.WorkflowAppActionParameter{}
|
||||||
|
for _, parameter := range trigger.Parameters {
|
||||||
|
action.Parameters = append(action.Parameters, shuffle.WorkflowAppActionParameter{
|
||||||
|
Name: parameter.Name,
|
||||||
|
Value: parameter.Value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger.LargeImage = ""
|
||||||
|
triggerData, err := json.Marshal(trigger)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[WARNING] Failed unmarshalling action: %s", err)
|
||||||
|
triggerData = []byte("Failed unmarshalling. Cancel execution!")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = runUserInput(topClient, action, workflowExecution.Workflow.ID, workflowExecution, workflowExecution.Authorization, string(triggerData), dockercli)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] Failed launching backend magic: %s", err)
|
||||||
|
os.Exit(3)
|
||||||
|
} else {
|
||||||
|
log.Printf("[INFO] Launched user input node succesfully!")
|
||||||
|
os.Exit(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//log.Printf("Handling action %#v", action)
|
||||||
|
}
|
||||||
|
|
||||||
appname := action.AppName
|
appname := action.AppName
|
||||||
appversion := action.AppVersion
|
appversion := action.AppVersion
|
||||||
appname = strings.Replace(appname, ".", "-", -1)
|
appname = strings.Replace(appname, ".", "-", -1)
|
||||||
@@ -1408,7 +1456,7 @@ func executionInit(workflowExecution shuffle.WorkflowExecution) error {
|
|||||||
nextActions := []string{}
|
nextActions := []string{}
|
||||||
extra := 0
|
extra := 0
|
||||||
|
|
||||||
results = workflowExecution.Results
|
//results = workflowExecution.Results
|
||||||
|
|
||||||
startAction := workflowExecution.Start
|
startAction := workflowExecution.Start
|
||||||
log.Printf("[INFO][%s] STARTACTION: %s", workflowExecution.ExecutionId, startAction)
|
log.Printf("[INFO][%s] STARTACTION: %s", workflowExecution.ExecutionId, startAction)
|
||||||
@@ -1980,7 +2028,7 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results = append(results, actionResult)
|
//results = append(results, actionResult)
|
||||||
|
|
||||||
log.Printf("[DEBUG][%s] In workflowQueue with transaction", workflowExecution.ExecutionId)
|
log.Printf("[DEBUG][%s] In workflowQueue with transaction", workflowExecution.ExecutionId)
|
||||||
runWorkflowExecutionTransaction(ctx, 0, workflowExecution.ExecutionId, actionResult, resp)
|
runWorkflowExecutionTransaction(ctx, 0, workflowExecution.ExecutionId, actionResult, resp)
|
||||||
@@ -2035,9 +2083,9 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
log.Printf(`[DEBUG][%s] Got result %s from %s. Execution status: %s. Save: %#v`, actionResult.ExecutionId, actionResult.Status, actionResult.Action.ID, workflowExecution.Status, dbSave)
|
log.Printf(`[DEBUG][%s] Got result %s from %s. Execution status: %s. Save: %#v`, actionResult.ExecutionId, actionResult.Status, actionResult.Action.ID, workflowExecution.Status, dbSave)
|
||||||
//dbSave := false
|
//dbSave := false
|
||||||
|
|
||||||
if len(results) != len(workflowExecution.Results) {
|
//if len(results) != len(workflowExecution.Results) {
|
||||||
log.Printf("[DEBUG][%s] There may have been an issue in transaction queue. Result lengths: %d vs %d. Should check which exists the base results, but not in entire execution, then append.", workflowExecution.ExecutionId, len(results), len(workflowExecution.Results))
|
// log.Printf("[DEBUG][%s] There may have been an issue in transaction queue. Result lengths: %d vs %d. Should check which exists the base results, but not in entire execution, then append.", workflowExecution.ExecutionId, len(results), len(workflowExecution.Results))
|
||||||
}
|
//}
|
||||||
|
|
||||||
// Validating that action results hasn't changed
|
// Validating that action results hasn't changed
|
||||||
// Handled using cachhing, so actually pretty fast
|
// Handled using cachhing, so actually pretty fast
|
||||||
|
|||||||
Reference in New Issue
Block a user