- Runtime Argument
+ {foundSourcenode !== undefined && foundSourcenode !== null ?
+ "Add Note"
+ :
+ "Runtime Argument"
+ }
+
{
: null*/}
:
- ((answer !== undefined && answer !== null) || (foundSourcenode !== undefined && foundSourcenode !== null)) ?
+ (foundSourcenode !== undefined && foundSourcenode !== null) ?
{disabledButtons && message.length > 0 ?
- {message}. You may close this window.
+ {message}
:
- {disabledButtons ? "Answered. You may close this window." : ""}
+ {disabledButtons ? "Already answered. You may close this window." : ""}
}
diff --git a/functions/onprem/orborus/go.mod b/functions/onprem/orborus/go.mod
index 1a7f57b1..ed7e5add 100644
--- a/functions/onprem/orborus/go.mod
+++ b/functions/onprem/orborus/go.mod
@@ -10,7 +10,7 @@ require (
github.com/docker/docker v28.3.3+incompatible
github.com/docker/go-connections v0.5.0
github.com/satori/go.uuid v1.2.0
- github.com/shuffle/shuffle-shared v0.9.14
+ github.com/shuffle/shuffle-shared v0.9.15
k8s.io/api v0.33.1
k8s.io/apimachinery v0.33.1
)
diff --git a/functions/onprem/orborus/go.sum b/functions/onprem/orborus/go.sum
index 2496c612..3818c38f 100644
--- a/functions/onprem/orborus/go.sum
+++ b/functions/onprem/orborus/go.sum
@@ -328,8 +328,8 @@ github.com/sendgrid/sendgrid-go v3.16.1+incompatible h1:zWhTmB0Y8XCDzeWIm2/BIt1G
github.com/sendgrid/sendgrid-go v3.16.1+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
-github.com/shuffle/shuffle-shared v0.9.14 h1:POkTHO+bByuv8HiKuCMSGgtpDKk86ISr6ooLG8vQfuE=
-github.com/shuffle/shuffle-shared v0.9.14/go.mod h1:PhDEizuz4SmJaSmy0+yrFWwD1mXVUsy8/knKlrqF1qw=
+github.com/shuffle/shuffle-shared v0.9.15 h1:Gc7c0pbWG6nHWSTkcfAnKgQgWCWfc6aDQ/BIu20z6bM=
+github.com/shuffle/shuffle-shared v0.9.15/go.mod h1:PhDEizuz4SmJaSmy0+yrFWwD1mXVUsy8/knKlrqF1qw=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
diff --git a/functions/onprem/orborus/orborus.go b/functions/onprem/orborus/orborus.go
index 507d5301..a6435b65 100755
--- a/functions/onprem/orborus/orborus.go
+++ b/functions/onprem/orborus/orborus.go
@@ -60,7 +60,7 @@ var sleepTime = 2
// Making it work on low-end machines even during busy times :)
// May cause some things to run slowly
-var maxConcurrency = 7
+var maxConcurrency = 25
// Timeout if something rashes
var workerTimeoutEnv = os.Getenv("SHUFFLE_ORBORUS_EXECUTION_TIMEOUT")
@@ -81,6 +81,7 @@ var workerContainerSecurityContext = os.Getenv("SHUFFLE_WORKER_CONTAINER_SECURIT
var appServiceAccountName = os.Getenv("SHUFFLE_APP_SERVICE_ACCOUNT_NAME")
var appPodSecurityContext = os.Getenv("SHUFFLE_APP_POD_SECURITY_CONTEXT")
var appContainerSecurityContext = os.Getenv("SHUFFLE_APP_CONTAINER_SECURITY_CONTEXT")
+var debug = os.Getenv("DEBUG") == "true"
// var baseimagename = "docker.pkg.github.com/shuffle/shuffle"
// var baseimagename = "ghcr.io/frikky"
@@ -218,6 +219,10 @@ func skipCheckInCleanup(name string) bool {
}
func cleanupExistingNodes(ctx context.Context) error {
+ if cleanupEnv == "false" {
+ log.Printf("[INFO] Skipping cleanup of existing workers as CLEANUP is set to false. This should be auto-discovered during executions then instead.")
+ return nil
+ }
if isKubernetes == "true" {
// Cleanup all workers created by orborus and all apps created by workers.
@@ -2173,6 +2178,12 @@ func main() {
client := shuffle.GetExternalClient(baseUrl)
fullUrl := fmt.Sprintf("%s/api/v1/workflows/queue", baseUrl)
+ // Increases default concurrency to 50 for swarm
+ if maxConcurrency < 50 && (swarmConfig == "run" || swarmConfig == "swarm") {
+ fullUrl += "?amount=50"
+ }
+
+
if isKubernetes == "true" {
log.Printf("[INFO] Finished configuring kubernetes environment. Connecting to %s", fullUrl)
} else {
@@ -3926,7 +3937,6 @@ func sendWorkerRequest(workflowExecution shuffle.ExecutionRequest, image string,
}
identifier := "shuffle-workers"
-
if isKubernetes == "true" {
if shuffle.IsRunningInCluster() {
log.Printf("[INFO] Running in Kubernetes cluster")
@@ -3938,7 +3948,9 @@ func sendWorkerRequest(workflowExecution shuffle.ExecutionRequest, image string,
// Specific to debugging
if len(workerServerUrl) == 0 {
- log.Printf("[INFO] Using default worker server url as previous is invalid: %s", streamUrl)
+ if debug {
+ log.Printf("[INFO] Using default worker server url as previous is invalid: %s. Swapping to shuffle-workers:33333", streamUrl)
+ }
}
streamUrl = fmt.Sprintf("http://shuffle-workers:33333/api/v1/execute")
@@ -3993,7 +4005,7 @@ func sendWorkerRequest(workflowExecution shuffle.ExecutionRequest, image string,
newresp, err := client.Do(req)
if err != nil {
// Connection refused?
- log.Printf("[ERROR] Error running worker request to %s (1): %s", streamUrl, err)
+ log.Printf("[ERROR][%s] Error running worker request to %s (1): %s", workflowExecution.ExecutionId, streamUrl, err)
if strings.Contains(fmt.Sprintf("%s", err), "connection refused") || strings.Contains(fmt.Sprintf("%s", err), "EOF") {
workerImage := fmt.Sprintf("ghcr.io/shuffle/shuffle-worker:%s", workerVersion)
@@ -4026,7 +4038,11 @@ func sendWorkerRequest(workflowExecution shuffle.ExecutionRequest, image string,
log.Printf("[WARNING] POTENTIAL error running worker request (2) - status code is %d for %s, not 200. Body: %s", newresp.StatusCode, streamUrl, string(body))
// In case of old executions
- if strings.Contains(string(body), "Bad status ") {
+ if strings.Contains(strings.ToLower(string(body)), "bad status ") {
+ return nil
+ }
+
+ if strings.Contains(strings.ToLower(string(body)), "no apps to handle") {
return nil
}
@@ -4040,7 +4056,7 @@ func sendWorkerRequest(workflowExecution shuffle.ExecutionRequest, image string,
debugCommand = fmt.Sprintf("kubectl logs -n %s deployment/shuffle-workers | grep %s", kubernetesNamespace, workflowExecution.ExecutionId)
}
- log.Printf("[DEBUG] Ran worker from request with execution ID: %s. Worker URL: %s. DEBUGGING:\n%s", workflowExecution.ExecutionId, streamUrl, debugCommand)
+ log.Printf("[DEBUG][%s] Ran worker from requests. Worker URL: %s. DEBUGGING:\n%s", workflowExecution.ExecutionId, streamUrl, debugCommand)
return nil
}
diff --git a/functions/onprem/worker/go.mod b/functions/onprem/worker/go.mod
index ded2c196..0821bc1c 100644
--- a/functions/onprem/worker/go.mod
+++ b/functions/onprem/worker/go.mod
@@ -11,7 +11,7 @@ require (
github.com/docker/docker v28.3.3+incompatible
github.com/gorilla/mux v1.8.1
github.com/satori/go.uuid v1.2.0
- github.com/shuffle/shuffle-shared v0.9.14
+ github.com/shuffle/shuffle-shared v0.9.15
github.com/shuffle/singul v0.0.16
k8s.io/api v0.33.1
k8s.io/apimachinery v0.33.1
diff --git a/functions/onprem/worker/go.sum b/functions/onprem/worker/go.sum
index 2834c50b..0df9cc57 100644
--- a/functions/onprem/worker/go.sum
+++ b/functions/onprem/worker/go.sum
@@ -330,8 +330,8 @@ github.com/sendgrid/sendgrid-go v3.16.1+incompatible h1:zWhTmB0Y8XCDzeWIm2/BIt1G
github.com/sendgrid/sendgrid-go v3.16.1+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
-github.com/shuffle/shuffle-shared v0.9.14 h1:POkTHO+bByuv8HiKuCMSGgtpDKk86ISr6ooLG8vQfuE=
-github.com/shuffle/shuffle-shared v0.9.14/go.mod h1:PhDEizuz4SmJaSmy0+yrFWwD1mXVUsy8/knKlrqF1qw=
+github.com/shuffle/shuffle-shared v0.9.15 h1:Gc7c0pbWG6nHWSTkcfAnKgQgWCWfc6aDQ/BIu20z6bM=
+github.com/shuffle/shuffle-shared v0.9.15/go.mod h1:PhDEizuz4SmJaSmy0+yrFWwD1mXVUsy8/knKlrqF1qw=
github.com/shuffle/singul v0.0.16 h1:dW+0Mln9R1aUJ0fjikpWcxbjoQWqJHxe4kSxh2tQN5E=
github.com/shuffle/singul v0.0.16/go.mod h1:LYkp320A6gsoPlYbXUM+WvEPUVAuutlSsqnVKyRy4gs=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
diff --git a/functions/onprem/worker/worker.go b/functions/onprem/worker/worker.go
index 60efa0c7..c6b82823 100644
--- a/functions/onprem/worker/worker.go
+++ b/functions/onprem/worker/worker.go
@@ -304,7 +304,7 @@ func shutdown(workflowExecution shuffle.WorkflowExecution, nodeId string, reason
shutdownData, err := json.Marshal(workflowExecution)
if err == nil {
sendResult(workflowExecution, shutdownData)
- log.Printf("[WARNING][%s] Sent shutdown update with %d results and result value %s", workflowExecution.ExecutionId, len(workflowExecution.Results), reason)
+ //log.Printf("[WARNING][%s] Sent shutdown update with %d results and result value %s", workflowExecution.ExecutionId, len(workflowExecution.Results), reason)
} else {
log.Printf("[WARNING][%s] Failed to send update: %s", workflowExecution.ExecutionId, err)
}
@@ -413,7 +413,6 @@ func deployk8sApp(image string, identifier string, env []string) error {
}
log.Printf("[DEBUG] Deploying k8s app with identifier %s to namespace %s", identifier, kubernetesNamespace)
-
deployport, err := strconv.Atoi(os.Getenv("SHUFFLE_APP_EXPOSED_PORT"))
if err != nil {
deployport = 80
@@ -2022,7 +2021,9 @@ func executionInit(workflowExecution shuffle.WorkflowExecution) error {
}
if len(onpremApps) == 0 {
- return errors.New(fmt.Sprintf("No apps to handle onprem (%s)", environment))
+ //return errors.New(fmt.Sprintf("No apps to handle onprem (%s)", environment))
+ log.Printf("[INFO][%s] No apps to handle onprem (%s). Returning 200 OK anyway", workflowExecution.ExecutionId, environment)
+ return nil
}
pullOptions := dockerimage.PullOptions{}
@@ -2803,7 +2804,7 @@ func sendSelfRequest(actionResult shuffle.ActionResult) {
if err != nil {
log.Printf("[ERROR][%s] Failed reading body: %s", actionResult.ExecutionId, err)
} else {
- log.Printf("[DEBUG][%s] NEWRESP (from backend - 2): %s", actionResult.ExecutionId, string(body))
+ log.Printf("[DEBUG][%s] Sent update to backend - 2: %s", actionResult.ExecutionId, string(body))
}
}
}
@@ -2863,7 +2864,7 @@ func sendResult(workflowExecution shuffle.WorkflowExecution, data []byte) {
if err != nil {
log.Printf("[ERROR][%s] Failed reading body: %s", workflowExecution.ExecutionId, err)
} else {
- log.Printf("[DEBUG][%s] NEWRESP (from backend): %s", workflowExecution.ExecutionId, string(body))
+ log.Printf("[DEBUG][%s] Sent request to backend: %s", workflowExecution.ExecutionId, string(body))
}
}
}
@@ -3079,12 +3080,9 @@ func getAvailablePort() (net.Listener, error) {
listener, err := net.Listen("tcp", ":0")
if err != nil {
log.Printf("[WARNING] Failed to assign port by default. Defaulting to 5001")
- //return ":5001"
return nil, err
}
- //defer listener.Close()
-
return listener, nil
//return fmt.Sprintf(":%d", port)
}
@@ -3179,7 +3177,7 @@ func findActiveSwarmNodes(dockercli *dockerclient.Client) (int64, error) {
}
/*** STARTREMOVE ***/
-func deploySwarmService(dockercli *dockerclient.Client, name, image string, deployport int, retry bool) error {
+func deploySwarmService(dockercli *dockerclient.Client, name, image string, deployport int, inputReplicas int64, retry bool) error {
log.Printf("[DEBUG] Deploying service for %s to swarm on port %d", name, deployport)
//containerName := fmt.Sprintf("shuffle-worker-%s", parsedUuid)
@@ -3240,6 +3238,15 @@ func deploySwarmService(dockercli *dockerclient.Client, name, image string, depl
log.Printf("[DEBUG] SHUFFLE_APP_REPLICAS set to value %#v. Trying to overwrite default (%d/node)", scaleReplicas, replicas)
}
+ // Max scale as well
+ if inputReplicas > 0 && inputReplicas < 100 {
+ if replicas != uint64(inputReplicas) {
+ log.Printf("[DEBUG] Overwriting replicas to %d/node as inputReplicas is set to %d", inputReplicas, inputReplicas)
+ }
+
+ replicas = uint64(inputReplicas)
+ }
+
cnt, err := findActiveSwarmNodes(dockercli)
if err != nil {
log.Printf("[ERROR] Unable to find active swarm nodes: %s", err)
@@ -3380,10 +3387,20 @@ func deploySwarmService(dockercli *dockerclient.Client, name, image string, depl
// Retry deploying the service (once)
if !retry {
- return deploySwarmService(dockercli, name, image, deployport, true)
+ return deploySwarmService(dockercli, name, image, deployport, -1, true)
}
}
+ // For port mapping.
+ if strings.Contains(fmt.Sprintf("%s", err), "InvalidArgument") && strings.Contains(fmt.Sprintf("%s", err), "is already in use") {
+ //log.Printf("\n\n[WARNING] Port %d is already allocated. Trying to deploy on next port.\n\n", deployport)
+
+ // Random sleep 1-4 seconds
+ time.Sleep(time.Duration(rand.Intn(4)+1) * time.Second)
+
+ return deploySwarmService(dockercli, name, image, deployport+1, -1, retry)
+ }
+
log.Printf("[DEBUG] Failed deploying %s with image %s: %s", name, image, err)
return err
}
@@ -3397,6 +3414,11 @@ func deploySwarmService(dockercli *dockerclient.Client, name, image string, depl
func findAppInfo(image, name string, redeploy bool) (int, error) {
+ // Sleep between 0 and 1.5 second - ensures deployments have a higher
+ // chance of being successful
+ time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
+
+
highest := baseport
exposedPort := -1
@@ -3462,6 +3484,7 @@ func findAppInfo(image, name string, redeploy bool) (int, error) {
continue
}
+ // This seems to have concurrency issues
portMappings[service.Spec.Annotations.Name] = int(endpoint.PublishedPort)
if int(endpoint.PublishedPort) > highest {
highest = int(endpoint.PublishedPort)
@@ -3478,10 +3501,11 @@ func findAppInfo(image, name string, redeploy bool) (int, error) {
}
if redeploy {
+ log.Printf("Found it! Service: %s with image %s on port %d", name, image, exposedPort)
// Remove the service and redeploy it.
// There are cases where the service doesn't update properly
- // Check when the last update happened. If it was within the last 5 minutes, skip
- if int(time.Since(service.UpdatedAt).Seconds()) > 600 {
+ // Check when the last update happened. If it was within the last few minutes, skip
+ if int(time.Since(service.UpdatedAt).Seconds()) > 60 {
log.Printf("[INFO] Attempting redeploy of app %s with image %s since it is more than 10 minutes since last attempt with failure.", name, image)
@@ -3493,12 +3517,16 @@ func findAppInfo(image, name string, redeploy bool) (int, error) {
log.Printf("[ERROR] Failed auto-removing service %s: %s", name, err)
} else {
log.Printf("[INFO] Auto-removed service %s successfully (rebuild due to redeploy).", name)
- time.Sleep(10 * time.Second)
+
+ // Sleep between 8 and 12 seconds
+ time.Sleep(time.Duration(rand.Intn(4)+8) * time.Second)
+ replicas := service.Spec.Mode.Replicated.Replicas
err = deploySwarmService(
dockercli,
name,
image,
exposedPort,
+ int64(*replicas),
false,
)
if err != nil {
@@ -3508,7 +3536,7 @@ func findAppInfo(image, name string, redeploy bool) (int, error) {
}
}
} else {
- //log.Printf("[INFO] NOT redeploying service %s since it was updated less than 10 minutes ago.", name)
+ //log.Printf("[INFO] NOT redeploying service %s since it was updated less than 3 minutes ago.", name)
}
}
@@ -3536,7 +3564,7 @@ func findAppInfo(image, name string, redeploy bool) (int, error) {
}
highest += 1
- err = deploySwarmService(dockercli, name, image, highest, false)
+ err = deploySwarmService(dockercli, name, image, highest, -1, false)
if err != nil {
log.Printf("[WARNING] NOT Found service: %s. error: %s", name, err)
return highest, err
@@ -3898,7 +3926,7 @@ func sendAppRequest(ctx context.Context, incomingUrl, appName string, port int,
// Has some issues with loading when running multiple workers and such.
func baseDeploy() {
- var cli *dockerclient.Client
+ //var cli *dockerclient.Client
//var err error
if isKubernetes != "true" {
@@ -3954,14 +3982,19 @@ func baseDeploy() {
env = append(env, fmt.Sprintf("SHUFFLE_APP_SDK_TIMEOUT=%s", os.Getenv("SHUFFLE_APP_SDK_TIMEOUT")))
}
- identifier := fmt.Sprintf("%s_%s_%s_%s", appname, appversion, action.ID, workflowExecution.ExecutionId)
- if strings.Contains(identifier, " ") {
- identifier = strings.ReplaceAll(identifier, " ", "-")
- }
+ identifier := fmt.Sprintf("%s_%s", appname, appversion)
+ //identifier := fmt.Sprintf("%s_%s_%s_%s", appname, appversion, action.ID, workflowExecution.ExecutionId)
+ //if strings.Contains(identifier, " ") {
+ // identifier = strings.ReplaceAll(identifier, " ", "-")
+ //}
//deployApp(cli, value, identifier, env, workflowExecution, action)
log.Printf("[DEBUG] Deploying app with identifier %s to ensure basic apps are available from the get-go", identifier)
- go deployApp(cli, value, identifier, env, workflowExecution, action)
+
+ //findAppInfo("frikky/shuffle:http_1.4.0", "http_1-4-0", true)
+ go findAppInfo(value, identifier, false)
+
+ //go deployApp(cli, value, identifier, env, workflowExecution, action)
//err := deployApp(cli, value, identifier, env, workflowExecution, action)
//if err != nil {
// log.Printf("[DEBUG] Failed deploying app %s: %s", value, err)
@@ -4281,12 +4314,10 @@ func checkStandaloneRun() {
// Initial loop etc
func main() {
- // Testing swarm auto-replacements.
- //findAppInfo("frikky/shuffle:shuffle-ai_1.0.0", "shuffle-ai_1-0-0", true)
- //findAppInfo("frikky/shuffle:shuffle-ai_1.0.0", "singul_1-0-0", true)
+ // Testing swarm auto-replacements. This also tests ports
+ // in rapid succession
checkStandaloneRun()
-
if os.Getenv("DEBUG") == "true" {
debug = true
@@ -4297,9 +4328,10 @@ func main() {
/*** STARTREMOVE ***/
if os.Getenv("SHUFFLE_SWARM_CONFIG") == "run" || os.Getenv("SHUFFLE_SWARM_CONFIG") == "swarm" {
logsDisabled = "true"
+ os.Setenv("SHUFFLE_LOGS_DISABLED", "true")
}
-
/*** ENDREMOVE ***/
+
// Elasticsearch necessary to ensure we'ren ot running with Datastore configurations for minimal/maximal data sizes
// Recursive import kind of :)
_, err := shuffle.RunInit(*shuffle.GetDatastore(), *shuffle.GetStorage(), "", "worker", true, "elasticsearch", false, 0)
@@ -4757,7 +4789,7 @@ func runWebserver(listener net.Listener) {
//log.Fatal(http.Serve(listener, nil))
- log.Printf("[DEBUG] NEW webserver setup")
+ log.Printf("[DEBUG] NEW webserver setup. Port: %s", listener.Addr().String())
http.Handle("/", r)
srv := http.Server{