Feature: can now attach to and watch running execution
This commit is contained in:
+20
-19
@@ -29,6 +29,8 @@ class AppBase:
|
|||||||
if isinstance(self.action, str):
|
if isinstance(self.action, str):
|
||||||
self.action = json.loads(self.action)
|
self.action = json.loads(self.action)
|
||||||
|
|
||||||
|
# FIXME: Add more info like logs in here.
|
||||||
|
# Docker logs: https://forums.docker.com/t/docker-logs-inside-the-docker-container/68190/2
|
||||||
def send_result(self, action_result, headers, stream_path):
|
def send_result(self, action_result, headers, stream_path):
|
||||||
if action_result["status"] == "EXECUTING":
|
if action_result["status"] == "EXECUTING":
|
||||||
action_result["status"] = "FAILURE"
|
action_result["status"] = "FAILURE"
|
||||||
@@ -187,7 +189,7 @@ class AppBase:
|
|||||||
|
|
||||||
paramlist.append(baseitem)
|
paramlist.append(baseitem)
|
||||||
|
|
||||||
print("PARAMLIST: %s" % paramlist)
|
#print("PARAMLIST: %s" % paramlist)
|
||||||
|
|
||||||
#newlist[subitem[0]]
|
#newlist[subitem[0]]
|
||||||
#if len(newlist) > 0:
|
#if len(newlist) > 0:
|
||||||
@@ -198,7 +200,7 @@ class AppBase:
|
|||||||
#print("Listlengths: %s" % listlengths)
|
#print("Listlengths: %s" % listlengths)
|
||||||
#paramlist = [baseparams]
|
#paramlist = [baseparams]
|
||||||
|
|
||||||
print("Return paramlist: %s" % paramlist)
|
#print("[INFO] Return paramlist: %s" % paramlist)
|
||||||
return paramlist
|
return paramlist
|
||||||
|
|
||||||
|
|
||||||
@@ -880,14 +882,13 @@ class AppBase:
|
|||||||
actionname_lower = parsersplit[0][1:].lower()
|
actionname_lower = parsersplit[0][1:].lower()
|
||||||
|
|
||||||
#Actionname: Start_node
|
#Actionname: Start_node
|
||||||
|
print(f"\n[INFO] Actionname: {actionname_lower}")
|
||||||
print(f"\nActionname: {actionname_lower}")
|
|
||||||
|
|
||||||
# 1. Find the action
|
# 1. Find the action
|
||||||
baseresult = ""
|
baseresult = ""
|
||||||
|
|
||||||
appendresult = ""
|
appendresult = ""
|
||||||
print("Parsersplit length: %d" % len(parsersplit))
|
print("[INFO] Parsersplit length: %d" % len(parsersplit))
|
||||||
if (actionname_lower.startswith("exec ") or actionname_lower.startswith("webhook ") or actionname_lower.startswith("schedule ") or actionname_lower.startswith("userinput ") or actionname_lower.startswith("email_trigger ") or actionname_lower.startswith("trigger ")) and len(parsersplit) == 1:
|
if (actionname_lower.startswith("exec ") or actionname_lower.startswith("webhook ") or actionname_lower.startswith("schedule ") or actionname_lower.startswith("userinput ") or actionname_lower.startswith("email_trigger ") or actionname_lower.startswith("trigger ")) and len(parsersplit) == 1:
|
||||||
record = False
|
record = False
|
||||||
for char in actionname_lower:
|
for char in actionname_lower:
|
||||||
@@ -1276,7 +1277,7 @@ class AppBase:
|
|||||||
except requests.exceptions.ConnectionError as e:
|
except requests.exceptions.ConnectionError as e:
|
||||||
self.logger.exception(e)
|
self.logger.exception(e)
|
||||||
|
|
||||||
print("\n\nRETURNING BECAUSE A BRANCH FAILED\n\n")
|
print("\n\nRETURNING BECAUSE A BRANCH FAILED: %s\n\n" % tmpresult)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Replace name cus there might be issues
|
# Replace name cus there might be issues
|
||||||
@@ -1324,7 +1325,7 @@ class AppBase:
|
|||||||
|
|
||||||
if parameter["name"] == "body":
|
if parameter["name"] == "body":
|
||||||
bodyindex = counter
|
bodyindex = counter
|
||||||
print("PARAM: %s" % parameter)
|
#print("PARAM: %s" % parameter)
|
||||||
try:
|
try:
|
||||||
values = parameter["value_replace"]
|
values = parameter["value_replace"]
|
||||||
if values != None:
|
if values != None:
|
||||||
@@ -1601,27 +1602,27 @@ class AppBase:
|
|||||||
# "id": "body_replacement",
|
# "id": "body_replacement",
|
||||||
#})
|
#})
|
||||||
|
|
||||||
print("APP_SDK DONE: Starting NORMAL execution of function")
|
print("[INFO] APP_SDK DONE: Starting NORMAL execution of function")
|
||||||
print("Running with params (0): %s" % params)
|
#print("[INFO] Running with params (0): %s" % params)
|
||||||
newres = await func(**params)
|
newres = await func(**params)
|
||||||
print("Returned from execution.")
|
print("[INFO] Returned from execution.")
|
||||||
if isinstance(newres, tuple):
|
if isinstance(newres, tuple):
|
||||||
print("Handling return as tuple")
|
print("[INFO] Handling return as tuple")
|
||||||
# Handles files.
|
# Handles files.
|
||||||
filedata = ""
|
filedata = ""
|
||||||
file_ids = []
|
file_ids = []
|
||||||
print("TUPLE: %s" % newres[1])
|
print("TUPLE: %s" % newres[1])
|
||||||
if isinstance(newres[1], list):
|
if isinstance(newres[1], list):
|
||||||
print("HANDLING LIST FROM RET")
|
print("[INFO] HANDLING LIST FROM RET")
|
||||||
file_ids = self.set_files(newres[1])
|
file_ids = self.set_files(newres[1])
|
||||||
elif isinstance(newres[1], object):
|
elif isinstance(newres[1], object):
|
||||||
print("Handling JSON from ret")
|
print("[INFO] Handling JSON from ret")
|
||||||
file_ids = self.set_files([newres[1]])
|
file_ids = self.set_files([newres[1]])
|
||||||
elif isinstance(newres[1], str):
|
elif isinstance(newres[1], str):
|
||||||
print("Handling STRING from ret")
|
print("[INFO] Handling STRING from ret")
|
||||||
file_ids = self.set_files([newres[1]])
|
file_ids = self.set_files([newres[1]])
|
||||||
else:
|
else:
|
||||||
print("NO FILES TO HANDLE")
|
print("[INFO] NO FILES TO HANDLE")
|
||||||
|
|
||||||
tmp_result = {
|
tmp_result = {
|
||||||
"result": newres[0],
|
"result": newres[0],
|
||||||
@@ -1630,7 +1631,7 @@ class AppBase:
|
|||||||
|
|
||||||
result = json.dumps(tmp_result)
|
result = json.dumps(tmp_result)
|
||||||
elif isinstance(newres, str):
|
elif isinstance(newres, str):
|
||||||
print("Handling return as string")
|
print("[INFO] Handling return as string")
|
||||||
result += newres
|
result += newres
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -1639,13 +1640,13 @@ class AppBase:
|
|||||||
result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres)
|
result += "Failed autocasting. Can't handle %s type from function. Must be string" % type(newres)
|
||||||
print("Can't handle type %s value from function" % (type(newres)))
|
print("Can't handle type %s value from function" % (type(newres)))
|
||||||
|
|
||||||
print("POST NEWRES RESULT: ", result)
|
print("[INFO] POST NEWRES RESULT: ", result)
|
||||||
else:
|
else:
|
||||||
print("APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters))
|
print("[INFO] APP_SDK DONE: Starting MULTI execution (length: %d) with values %s" % (minlength, multi_parameters))
|
||||||
# 1. Use number of executions based on the arrays being similar
|
# 1. Use number of executions based on the arrays being similar
|
||||||
# 2. Find the right value from the parsed multi_params
|
# 2. Find the right value from the parsed multi_params
|
||||||
|
|
||||||
print("Running WITHOUT outer loop")
|
print("[INFO] Running WITHOUT outer loop")
|
||||||
json_object = False
|
json_object = False
|
||||||
results = await self.run_recursed_items(func, multi_parameters, {})
|
results = await self.run_recursed_items(func, multi_parameters, {})
|
||||||
if isinstance(results, dict) or isinstance(results, list):
|
if isinstance(results, dict) or isinstance(results, list):
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
NAME=shuffle-app_sdk
|
NAME=shuffle-app_sdk
|
||||||
VERSION=0.8.42
|
VERSION=0.8.43
|
||||||
|
|
||||||
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
|
docker rmi docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION --force
|
||||||
docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
|
docker build . -t frikky/shuffle:app_sdk -t frikky/$NAME:$VERSION -t docker.pkg.github.com/frikky/shuffle/$NAME:$VERSION -t ghcr.io/frikky/$NAME:$VERSION
|
||||||
|
|||||||
+53
-23
@@ -486,10 +486,11 @@ func increaseStatisticsField(ctx context.Context, fieldname, id string, amount i
|
|||||||
statisticsItem.Data = append(statisticsItem.Data, newData)
|
statisticsItem.Data = append(statisticsItem.Data, newData)
|
||||||
|
|
||||||
// New struct, to not add body, author etc
|
// New struct, to not add body, author etc
|
||||||
if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil {
|
// FIXME - reintroduce
|
||||||
log.Printf("Error stats to %s: %s", fieldname, err)
|
//if _, err := dbclient.Put(ctx, key, &statisticsItem); err != nil {
|
||||||
return err
|
// log.Printf("Error stats to %s: %s", fieldname, err)
|
||||||
}
|
// return err
|
||||||
|
//}
|
||||||
|
|
||||||
//log.Printf("Stats: %#v", statisticsItem)
|
//log.Printf("Stats: %#v", statisticsItem)
|
||||||
|
|
||||||
@@ -939,7 +940,6 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) {
|
|||||||
|
|
||||||
if workflowExecution.Status == "FINISHED" {
|
if workflowExecution.Status == "FINISHED" {
|
||||||
log.Printf("Workflowexecution is already FINISHED. No further action can be taken")
|
log.Printf("Workflowexecution is already FINISHED. No further action can be taken")
|
||||||
|
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflowexecution is already finished because of %s with status %s"}`, workflowExecution.LastNode, workflowExecution.Status)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Workflowexecution is already finished because of %s with status %s"}`, workflowExecution.LastNode, workflowExecution.Status)))
|
||||||
return
|
return
|
||||||
@@ -1025,6 +1025,8 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resultLength := len(workflowExecution.Results)
|
resultLength := len(workflowExecution.Results)
|
||||||
|
dbSave := false
|
||||||
|
setExecution := true
|
||||||
//tx, err := dbclient.NewTransaction(ctx)
|
//tx, err := dbclient.NewTransaction(ctx)
|
||||||
//if err != nil {
|
//if err != nil {
|
||||||
// log.Printf("client.NewTransaction: %v", err)
|
// log.Printf("client.NewTransaction: %v", err)
|
||||||
@@ -1044,15 +1046,17 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
if actionResult.Status == "ABORTED" || actionResult.Status == "FAILURE" {
|
if actionResult.Status == "ABORTED" || actionResult.Status == "FAILURE" {
|
||||||
log.Printf("[WARNING] Actionresult is %s for node %s in %s. Should set workflowExecution and exit all running functions", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId)
|
dbSave = true
|
||||||
|
|
||||||
newResults := []ActionResult{}
|
newResults := []ActionResult{}
|
||||||
childNodes := []string{}
|
childNodes := []string{}
|
||||||
if workflowExecution.Workflow.Configuration.ExitOnError {
|
if workflowExecution.Workflow.Configuration.ExitOnError {
|
||||||
|
log.Printf("[WARNING] Actionresult is %s for node %s in %s. Should set workflowExecution and exit all running functions", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId)
|
||||||
workflowExecution.Status = actionResult.Status
|
workflowExecution.Status = actionResult.Status
|
||||||
workflowExecution.LastNode = actionResult.Action.ID
|
workflowExecution.LastNode = actionResult.Action.ID
|
||||||
// Find underlying nodes and add them
|
// Find underlying nodes and add them
|
||||||
} else {
|
} else {
|
||||||
|
log.Printf("[WARNING] Actionresult is %s for node %s in %s. Continuing anyway because of workflow configuration.", actionResult.Status, actionResult.Action.ID, workflowExecution.ExecutionId)
|
||||||
// Finds ALL childnodes to set them to SKIPPED
|
// Finds ALL childnodes to set them to SKIPPED
|
||||||
childNodes = findChildNodes(*workflowExecution, actionResult.Action.ID)
|
childNodes = findChildNodes(*workflowExecution, actionResult.Action.ID)
|
||||||
// Remove duplicates
|
// Remove duplicates
|
||||||
@@ -1077,6 +1081,15 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resultExists := false
|
||||||
|
for _, result := range workflowExecution.Results {
|
||||||
|
if result.Action.ID == curAction.ID {
|
||||||
|
resultExists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !resultExists {
|
||||||
// Check parents are done here. Only add it IF all parents are skipped
|
// Check parents are done here. Only add it IF all parents are skipped
|
||||||
skipNodeAdd := false
|
skipNodeAdd := false
|
||||||
for _, branch := range workflowExecution.Workflow.Branches {
|
for _, branch := range workflowExecution.Workflow.Branches {
|
||||||
@@ -1114,14 +1127,19 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cleans up aborted, and always gives a result
|
// Cleans up aborted, and always gives a result
|
||||||
lastResult := ""
|
lastResult := ""
|
||||||
// type ActionResult struct {
|
// type ActionResult struct {
|
||||||
for _, result := range workflowExecution.Results {
|
for _, result := range workflowExecution.Results {
|
||||||
|
if actionResult.Action.ID == result.Action.ID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if result.Status == "EXECUTING" {
|
if result.Status == "EXECUTING" {
|
||||||
result.Status = actionResult.Status
|
result.Status = actionResult.Status
|
||||||
result.Result = "Aborted because of error in another node"
|
result.Result = "Aborted because of error in another node (2)"
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(result.Result) > 0 {
|
if len(result.Result) > 0 {
|
||||||
@@ -1152,17 +1170,24 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
// Find the appropriate action
|
// Find the appropriate action
|
||||||
if len(workflowExecution.Results) > 0 {
|
if len(workflowExecution.Results) > 0 {
|
||||||
// FIXME
|
// FIXME
|
||||||
|
skip := false
|
||||||
found := false
|
found := false
|
||||||
outerindex := 0
|
outerindex := 0
|
||||||
for index, item := range workflowExecution.Results {
|
for index, item := range workflowExecution.Results {
|
||||||
if item.Action.ID == actionResult.Action.ID {
|
if item.Action.ID == actionResult.Action.ID {
|
||||||
found = true
|
found = true
|
||||||
|
if item.Status == actionResult.Status {
|
||||||
|
skip = true
|
||||||
|
}
|
||||||
|
|
||||||
outerindex = index
|
outerindex = index
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if found {
|
if skip {
|
||||||
|
//log.Printf("Both are %s. Skipping this node", item.Status)
|
||||||
|
} else if found {
|
||||||
// If result exists and execution variable exists, update execution value
|
// If result exists and execution variable exists, update execution value
|
||||||
//log.Printf("Exec var backend: %s", workflowExecution.Results[outerindex].Action.ExecutionVariable.Name)
|
//log.Printf("Exec var backend: %s", workflowExecution.Results[outerindex].Action.ExecutionVariable.Name)
|
||||||
actionVarName := workflowExecution.Results[outerindex].Action.ExecutionVariable.Name
|
actionVarName := workflowExecution.Results[outerindex].Action.ExecutionVariable.Name
|
||||||
@@ -1178,14 +1203,14 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[INFO] Updating %s in %s from %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, workflowExecution.Results[outerindex].Status, actionResult.Status)
|
log.Printf("[INFO] Updating %s in workflow %s from %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, workflowExecution.Results[outerindex].Status, actionResult.Status)
|
||||||
workflowExecution.Results[outerindex] = actionResult
|
workflowExecution.Results[outerindex] = actionResult
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[INFO] Setting value of %s in %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status)
|
log.Printf("[INFO] Setting value of %s in workflow %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status)
|
||||||
workflowExecution.Results = append(workflowExecution.Results, actionResult)
|
workflowExecution.Results = append(workflowExecution.Results, actionResult)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[INFO] Setting value of %s in %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status)
|
log.Printf("[INFO] Setting value of %s in workflow %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, actionResult.Status)
|
||||||
workflowExecution.Results = append(workflowExecution.Results, actionResult)
|
workflowExecution.Results = append(workflowExecution.Results, actionResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1268,6 +1293,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
_ = skippedNodes
|
_ = skippedNodes
|
||||||
|
|
||||||
if finished {
|
if finished {
|
||||||
|
dbSave = true
|
||||||
log.Printf("[INFO] Execution of %s finished.", workflowExecution.ExecutionId)
|
log.Printf("[INFO] Execution of %s finished.", workflowExecution.ExecutionId)
|
||||||
//log.Println("Might be finished based on length of results and everything being SUCCESS or FINISHED - VERIFY THIS. Setting status to finished.")
|
//log.Println("Might be finished based on length of results and everything being SUCCESS or FINISHED - VERIFY THIS. Setting status to finished.")
|
||||||
|
|
||||||
@@ -1299,6 +1325,7 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
tmpJson, err := json.Marshal(workflowExecution)
|
tmpJson, err := json.Marshal(workflowExecution)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if len(tmpJson) >= 1048487 {
|
if len(tmpJson) >= 1048487 {
|
||||||
|
dbSave = true
|
||||||
log.Printf("[ERROR] Result length is too long! Need to reduce result size")
|
log.Printf("[ERROR] Result length is too long! Need to reduce result size")
|
||||||
|
|
||||||
// Result string `json:"result" datastore:"result,noindex"`
|
// Result string `json:"result" datastore:"result,noindex"`
|
||||||
@@ -1319,24 +1346,25 @@ func runWorkflowExecutionTransaction(ctx context.Context, attempts int64, workfl
|
|||||||
|
|
||||||
// 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
|
||||||
setExecution := true
|
|
||||||
cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId)
|
cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId)
|
||||||
if value, found := requestCache.Get(cacheKey); found {
|
if value, found := requestCache.Get(cacheKey); found {
|
||||||
parsedValue := value.(*WorkflowExecution)
|
parsedValue := value.(*WorkflowExecution)
|
||||||
if len(parsedValue.Results) > 0 && len(parsedValue.Results) != resultLength {
|
if len(parsedValue.Results) > 0 && len(parsedValue.Results) != resultLength {
|
||||||
setExecution = false
|
setExecution = false
|
||||||
if attempts > 5 {
|
if attempts > 5 {
|
||||||
log.Printf("\n\nSkipping execution input - %d vs %d. Attempts: (%d)\n\n", len(parsedValue.Results), resultLength, attempts)
|
//log.Printf("\n\nSkipping execution input - %d vs %d. Attempts: (%d)\n\n", len(parsedValue.Results), resultLength, attempts)
|
||||||
}
|
}
|
||||||
|
|
||||||
attempts += 1
|
attempts += 1
|
||||||
|
if len(workflowExecution.Results) <= len(workflowExecution.Workflow.Actions) {
|
||||||
runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp)
|
runWorkflowExecutionTransaction(ctx, attempts, workflowExecutionId, actionResult, resp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if setExecution {
|
if setExecution {
|
||||||
err = setWorkflowExecution(ctx, *workflowExecution, false)
|
err = setWorkflowExecution(ctx, *workflowExecution, dbSave)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.WriteHeader(401)
|
resp.WriteHeader(401)
|
||||||
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err)))
|
resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting workflowexecution actionresult: %s"}`, err)))
|
||||||
@@ -2546,7 +2574,7 @@ func abortExecution(resp http.ResponseWriter, request *http.Request) {
|
|||||||
for _, result := range workflowExecution.Results {
|
for _, result := range workflowExecution.Results {
|
||||||
if result.Status == "EXECUTING" {
|
if result.Status == "EXECUTING" {
|
||||||
result.Status = "ABORTED"
|
result.Status = "ABORTED"
|
||||||
result.Result = "Aborted because of error in another node"
|
result.Result = "Aborted because of error in another node (1)"
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(result.Result) > 0 {
|
if len(result.Result) > 0 {
|
||||||
@@ -3916,6 +3944,7 @@ func getSpecificWorkflow(resp http.ResponseWriter, request *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setWorkflowExecution(ctx context.Context, workflowExecution WorkflowExecution, dbSave bool) error {
|
func setWorkflowExecution(ctx context.Context, workflowExecution WorkflowExecution, dbSave bool) error {
|
||||||
|
//log.Printf("\n\n\nRESULT: %s\n\n\n", workflowExecution.Status)
|
||||||
if len(workflowExecution.ExecutionId) == 0 {
|
if len(workflowExecution.ExecutionId) == 0 {
|
||||||
log.Printf("Workflowexeciton executionId can't be empty.")
|
log.Printf("Workflowexeciton executionId can't be empty.")
|
||||||
return errors.New("ExecutionId can't be empty.")
|
return errors.New("ExecutionId can't be empty.")
|
||||||
@@ -3924,7 +3953,7 @@ func setWorkflowExecution(ctx context.Context, workflowExecution WorkflowExecuti
|
|||||||
cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId)
|
cacheKey := fmt.Sprintf("workflowexecution-%s", workflowExecution.ExecutionId)
|
||||||
//requestCache.Delete(cacheKey)
|
//requestCache.Delete(cacheKey)
|
||||||
requestCache.Set(cacheKey, &workflowExecution, cache.DefaultExpiration)
|
requestCache.Set(cacheKey, &workflowExecution, cache.DefaultExpiration)
|
||||||
if !dbSave {
|
if !dbSave && workflowExecution.Status == "EXECUTING" && len(workflowExecution.Results) > 1 {
|
||||||
//log.Printf("[WARNING] SHOULD skip DB saving for execution")
|
//log.Printf("[WARNING] SHOULD skip DB saving for execution")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -3955,7 +3984,7 @@ func getWorkflowExecution(ctx context.Context, id string) (*WorkflowExecution, e
|
|||||||
// log.Printf("Failed unmarshalling cached value: %s", err)
|
// log.Printf("Failed unmarshalling cached value: %s", err)
|
||||||
//}
|
//}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("[ERROR] Couldn't find key %s", cacheKey)
|
//log.Printf("[ERROR] Couldn't find key %s", cacheKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
key := datastore.NameKey("workflowexecution", strings.ToLower(id), nil)
|
key := datastore.NameKey("workflowexecution", strings.ToLower(id), nil)
|
||||||
@@ -4011,13 +4040,14 @@ func getAllWorkflows(ctx context.Context, orgId string) ([]Workflow, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setExampleresult(ctx context.Context, result AppExecutionExample) error {
|
func setExampleresult(ctx context.Context, result AppExecutionExample) error {
|
||||||
key := datastore.NameKey("example_result", result.ExampleId, nil)
|
// FIXME: Reintroduce this for stats
|
||||||
|
//key := datastore.NameKey("example_result", result.ExampleId, nil)
|
||||||
|
|
||||||
// New struct, to not add body, author etc
|
//// New struct, to not add body, author etc
|
||||||
if _, err := dbclient.Put(ctx, key, &result); err != nil {
|
//if _, err := dbclient.Put(ctx, key, &result); err != nil {
|
||||||
log.Printf("Error adding workflow: %s", err)
|
// log.Printf("Error adding workflow: %s", err)
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,25 +24,3 @@ curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c1
|
|||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
curl -XPOST http://localhost:5001/api/v1/workflows/425efd39-08e7-4390-9387-170c172775f7/execute -d '{"execution_argument":""}' -H "Authorization: Bearer db0373c6-1083-4dec-a05d-3ba73f02ccd4"
|
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ const AngularWorkflow = (props) => {
|
|||||||
// FIXME: Sort this by time
|
// FIXME: Sort this by time
|
||||||
setWorkflowExecutions(responseJson)
|
setWorkflowExecutions(responseJson)
|
||||||
}
|
}
|
||||||
|
alert.info("Refrshed executions")
|
||||||
//setWorkflowExecutions(responseJson)
|
//setWorkflowExecutions(responseJson)
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -3676,6 +3677,22 @@ const AngularWorkflow = (props) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const headerSize = 68
|
||||||
|
const rightsidebarStyle = {
|
||||||
|
position: "fixed",
|
||||||
|
right: 0,
|
||||||
|
top: headerSize+1,
|
||||||
|
height: "100%",
|
||||||
|
bottom: 0,
|
||||||
|
minWidth: 350,
|
||||||
|
maxWidth: 350,
|
||||||
|
borderLeft: "1px solid rgb(91, 96, 100)",
|
||||||
|
overflow: "scroll",
|
||||||
|
overflowX: "auto",
|
||||||
|
overflowY: "auto",
|
||||||
|
zIndex: 1000,
|
||||||
|
}
|
||||||
|
|
||||||
const appApiView = Object.getOwnPropertyNames(selectedAction).length > 0 ?
|
const appApiView = Object.getOwnPropertyNames(selectedAction).length > 0 ?
|
||||||
<div style={appApiViewStyle}>
|
<div style={appApiViewStyle}>
|
||||||
<div style={{display: "flex", minHeight: 40, marginBottom: 30}}>
|
<div style={{display: "flex", minHeight: 40, marginBottom: 30}}>
|
||||||
@@ -3757,7 +3774,7 @@ const AngularWorkflow = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
{selectedAction.authentication !== undefined && selectedAction.authentication.length > 0 ?
|
{selectedAction.authentication !== undefined && selectedAction.authentication.length > 0 ?
|
||||||
<div style={{marginTop: "20px"}}>
|
<div style={{marginTop: 20, overflow: "hidden",}}>
|
||||||
Authentication
|
Authentication
|
||||||
<div style={{display: "flex"}}>
|
<div style={{display: "flex"}}>
|
||||||
<Select
|
<Select
|
||||||
@@ -3776,7 +3793,7 @@ const AngularWorkflow = (props) => {
|
|||||||
setSelectedAction(selectedAction)
|
setSelectedAction(selectedAction)
|
||||||
setUpdate(Math.random())
|
setUpdate(Math.random())
|
||||||
}}
|
}}
|
||||||
style={{backgroundColor: inputColor, color: "white", height: "50px"}}
|
style={{backgroundColor: inputColor, color: "white", height: 50, maxWidth: rightsidebarStyle.maxWidth-80,}}
|
||||||
>
|
>
|
||||||
{selectedAction.authentication.map(data => (
|
{selectedAction.authentication.map(data => (
|
||||||
<MenuItem key={data.id} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
<MenuItem key={data.id} style={{backgroundColor: inputColor, color: "white"}} value={data}>
|
||||||
@@ -3794,11 +3811,11 @@ const AngularWorkflow = (props) => {
|
|||||||
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
|
if (curaction.selectedAuthentication === null || curaction.selectedAuthentication === undefined || curaction.selectedAuthentication.length === "")
|
||||||
*/}
|
*/}
|
||||||
<Tooltip color="primary" title={"Add authentication option"} placement="top">
|
<Tooltip color="primary" title={"Add authentication option"} placement="top">
|
||||||
<Button color="primary" style={{}} variant="text" onClick={() => {
|
<IconButton color="primary" style={{}} onClick={() => {
|
||||||
setAuthenticationModalOpen(true)
|
setAuthenticationModalOpen(true)
|
||||||
}}>
|
}}>
|
||||||
<AddIcon />
|
<AddIcon />
|
||||||
</Button>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -3926,22 +3943,6 @@ const AngularWorkflow = (props) => {
|
|||||||
: null
|
: null
|
||||||
|
|
||||||
|
|
||||||
const headerSize = 68
|
|
||||||
const rightsidebarStyle = {
|
|
||||||
position: "fixed",
|
|
||||||
right: 0,
|
|
||||||
top: headerSize+1,
|
|
||||||
height: "100%",
|
|
||||||
bottom: 0,
|
|
||||||
minWidth: "350px",
|
|
||||||
maxWidth: "350px",
|
|
||||||
borderLeft: "1px solid rgb(91, 96, 100)",
|
|
||||||
overflow: "scroll",
|
|
||||||
overflowX: "auto",
|
|
||||||
overflowY: "auto",
|
|
||||||
zIndex: 1000,
|
|
||||||
}
|
|
||||||
|
|
||||||
const setTriggerFolderWrapperMulti = event => {
|
const setTriggerFolderWrapperMulti = event => {
|
||||||
const { options } = event.target
|
const { options } = event.target
|
||||||
const value = []
|
const value = []
|
||||||
@@ -4556,6 +4557,9 @@ const AngularWorkflow = (props) => {
|
|||||||
setOpen(false)
|
setOpen(false)
|
||||||
deleteCondition(index)
|
deleteCondition(index)
|
||||||
}} key={"Delete"}>{"Delete"}</MenuItem>
|
}} key={"Delete"}>{"Delete"}</MenuItem>
|
||||||
|
<MenuItem style={{backgroundColor: inputColor, color: "white"}} onClick={() => {
|
||||||
|
//duplicateCondition(index)
|
||||||
|
}} key={"Duplicate"}>{"Duplicate"}</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -6081,6 +6085,17 @@ const AngularWorkflow = (props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper elevation={5} key={data.execution_id} square style={executionPaperStyle} onMouseOver={() => {}} onMouseOut={() => {}} onClick={() => {
|
<Paper elevation={5} key={data.execution_id} square style={executionPaperStyle} onMouseOver={() => {}} onMouseOut={() => {}} onClick={() => {
|
||||||
|
|
||||||
|
if (data.result === undefined || data.result === null || data.result.length === 0) {
|
||||||
|
setExecutionRequest({
|
||||||
|
"execution_id": data.execution_id,
|
||||||
|
"authorization": data.authorization,
|
||||||
|
})
|
||||||
|
start()
|
||||||
|
setExecutionRunning(true)
|
||||||
|
setExecutionRequestStarted(false)
|
||||||
|
console.log(data)
|
||||||
|
}
|
||||||
setExecutionModalView(1)
|
setExecutionModalView(1)
|
||||||
setExecutionData(data)
|
setExecutionData(data)
|
||||||
}}>
|
}}>
|
||||||
@@ -6117,7 +6132,12 @@ const AngularWorkflow = (props) => {
|
|||||||
:
|
:
|
||||||
<div style={{padding: 25, maxWidth: 365, overflowX: "hidden",}}>
|
<div style={{padding: 25, maxWidth: 365, overflowX: "hidden",}}>
|
||||||
<Breadcrumbs aria-label="breadcrumb" separator="›" style={{color: "white", fontSize: 16}}>
|
<Breadcrumbs aria-label="breadcrumb" separator="›" style={{color: "white", fontSize: 16}}>
|
||||||
<h2 style={{color: "rgba(255,255,255,0.5)", cursor: "pointer"}} onClick={() => {setExecutionModalView(0)}}>
|
<h2 style={{color: "rgba(255,255,255,0.5)", cursor: "pointer"}} onClick={() => {
|
||||||
|
setExecutionRunning(false)
|
||||||
|
stop()
|
||||||
|
getWorkflowExecution(props.match.params.key)
|
||||||
|
setExecutionModalView(0)
|
||||||
|
}}>
|
||||||
<ArrowBackIcon style={{marginRight: 7, }} />
|
<ArrowBackIcon style={{marginRight: 7, }} />
|
||||||
See other Executions
|
See other Executions
|
||||||
</h2>
|
</h2>
|
||||||
|
|||||||
Reference in New Issue
Block a user