forked from tangled.org/core
Monorepo for Tangled

spindle/engine: don't cancel the whole workflow group on the first error

Signed-off-by: Evan Jarrett <evan@evanjarrett.com>

authored by evan.jarrett.net and committed by Tangled 63c61679 0bf2bb0a

Changed files
+17 -20
spindle
engine
+17 -20
spindle/engine/engine.go
··· 3 3 import ( 4 4 "context" 5 5 "errors" 6 - "fmt" 7 6 "log/slog" 7 + "sync" 8 8 9 9 securejoin "github.com/cyphar/filepath-securejoin" 10 - "golang.org/x/sync/errgroup" 11 10 "tangled.org/core/notifier" 12 11 "tangled.org/core/spindle/config" 13 12 "tangled.org/core/spindle/db" ··· 31 30 } 32 31 } 33 32 34 - eg, ctx := errgroup.WithContext(ctx) 33 + var wg sync.WaitGroup 35 34 for eng, wfs := range pipeline.Workflows { 36 35 workflowTimeout := eng.WorkflowTimeout() 37 36 l.Info("using workflow timeout", "timeout", workflowTimeout) 38 37 39 38 for _, w := range wfs { 40 - eg.Go(func() error { 39 + wg.Add(1) 40 + go func() { 41 + defer wg.Done() 42 + 41 43 wid := models.WorkflowId{ 42 44 PipelineId: pipelineId, 43 45 Name: w.Name, ··· 45 47 46 48 err := db.StatusRunning(wid, n) 47 49 if err != nil { 48 - return err 50 + l.Error("failed to set workflow status to running", "wid", wid, "err", err) 51 + return 49 52 } 50 53 51 54 err = eng.SetupWorkflow(ctx, wid, &w) ··· 61 64 62 65 dbErr := db.StatusFailed(wid, err.Error(), -1, n) 63 66 if dbErr != nil { 64 - return dbErr 67 + l.Error("failed to set workflow status to failed", "wid", wid, "err", dbErr) 65 68 } 66 - return err 69 + return 67 70 } 68 71 defer eng.DestroyWorkflow(ctx, wid) 69 72 ··· 99 102 if errors.Is(err, ErrTimedOut) { 100 103 dbErr := db.StatusTimeout(wid, n) 101 104 if dbErr != nil { 102 - return dbErr 105 + l.Error("failed to set workflow status to timeout", "wid", wid, "err", dbErr) 103 106 } 104 107 } else { 105 108 dbErr := db.StatusFailed(wid, err.Error(), -1, n) 106 109 if dbErr != nil { 107 - return dbErr 110 + l.Error("failed to set workflow status to failed", "wid", wid, "err", dbErr) 108 111 } 109 112 } 110 - 111 - return fmt.Errorf("starting steps image: %w", err) 113 + return 112 114 } 113 115 } 114 116 115 117 err = db.StatusSuccess(wid, n) 116 118 if err != nil { 117 - return err 119 + l.Error("failed to set workflow status to success", "wid", wid, "err", err) 118 120 } 119 - 120 - return nil 121 - }) 121 + }() 122 122 } 123 123 } 124 124 125 - if err := eg.Wait(); err != nil { 126 - l.Error("failed to run one or more workflows", "err", err) 127 - } else { 128 - l.Info("successfully ran full pipeline") 129 - } 125 + wg.Wait() 126 + l.Info("all workflows completed") 130 127 }