executeActionsParallel executes actions in parallel
(ctx context.Context, client *csclient.Client, beaconID string, actions []Action)
| 149 | |
| 150 | // executeActionsParallel executes actions in parallel |
| 151 | func (e *Executor) executeActionsParallel(ctx context.Context, client *csclient.Client, beaconID string, actions []Action) error { |
| 152 | var wg sync.WaitGroup |
| 153 | errCh := make(chan error, len(actions)) |
| 154 | |
| 155 | for i, action := range actions { |
| 156 | // Check conditions before starting goroutine |
| 157 | if !e.evaluateActionConditions(action) { |
| 158 | e.logInfo("[%d] Conditions not met, skipping action: %s", i+1, action.Name) |
| 159 | continue |
| 160 | } |
| 161 | |
| 162 | wg.Add(1) |
| 163 | go func(idx int, act Action) { |
| 164 | defer wg.Done() |
| 165 | |
| 166 | e.logInfo("[%d] Executing action: %s (type: %s)", idx+1, act.Name, act.Type) |
| 167 | |
| 168 | output, err := e.executeAction(ctx, client, beaconID, act) |
| 169 | if err != nil { |
| 170 | e.logError("[%d] Action failed: %v", idx+1, err) |
| 171 | |
| 172 | // Execute on_failure actions |
| 173 | if len(act.OnFailure) > 0 { |
| 174 | e.logInfo("[%d] Executing on_failure actions", idx+1) |
| 175 | if failErr := e.executeActions(ctx, client, beaconID, act.OnFailure); failErr != nil { |
| 176 | errCh <- failErr |
| 177 | return |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | errCh <- fmt.Errorf("action %s failed: %w", act.Name, err) |
| 182 | return |
| 183 | } |
| 184 | |
| 185 | // Store output (thread-safe) |
| 186 | e.outputMu.Lock() |
| 187 | e.outputs[act.Name] = output |
| 188 | e.outputMu.Unlock() |
| 189 | |
| 190 | e.logInfo("[%d] Action completed successfully", idx+1) |
| 191 | |
| 192 | // Execute on_success actions |
| 193 | if len(act.OnSuccess) > 0 { |
| 194 | e.logInfo("[%d] Executing on_success actions", idx+1) |
| 195 | if succErr := e.executeActions(ctx, client, beaconID, act.OnSuccess); succErr != nil { |
| 196 | errCh <- succErr |
| 197 | } |
| 198 | } |
| 199 | }(i, action) |
| 200 | } |
| 201 | |
| 202 | wg.Wait() |
| 203 | close(errCh) |
| 204 | |
| 205 | // Check for errors |
| 206 | for err := range errCh { |
| 207 | return err |
| 208 | } |
no test coverage detected