Exec iterates through the prepResult slice, calling ExecItemFunc for each item with retries.
(ctx *PfContext, prepResult any)
| 431 | |
| 432 | // Exec iterates through the prepResult slice, calling ExecItemFunc for each item with retries. |
| 433 | func (bn *BatchNode) Exec(ctx *PfContext, prepResult any) (any, error) { |
| 434 | if prepResult == nil { |
| 435 | return []any{}, nil // Return empty slice if prep was nil |
| 436 | } |
| 437 | |
| 438 | // Type assertion to get the slice from Prep result |
| 439 | items, ok := prepResult.([]any) |
| 440 | if !ok { |
| 441 | return nil, newPocketFlowError(fmt.Sprintf("Prep phase of BatchNode %T did not return []any, got %T", bn, prepResult), nil) |
| 442 | } |
| 443 | |
| 444 | if len(items) == 0 { |
| 445 | return []any{}, nil // Return empty slice for empty input |
| 446 | } |
| 447 | |
| 448 | results := make([]any, len(items)) |
| 449 | var itemResult any |
| 450 | var lastItemErr error |
| 451 | currentRetry := 0 |
| 452 | |
| 453 | for i, item := range items { |
| 454 | lastItemErr = nil // Reset error for each item |
| 455 | itemSuccess := false |
| 456 | for currentRetry = 0; currentRetry < bn.MaxRetries; currentRetry++ { |
| 457 | itemResult, lastItemErr = bn.ExecItemFunc(ctx, bn.params, item) |
| 458 | if lastItemErr == nil { |
| 459 | itemSuccess = true |
| 460 | break // Success for this item |
| 461 | } |
| 462 | if currentRetry < bn.MaxRetries-1 && bn.WaitMilliseconds > 0 { |
| 463 | time.Sleep(bn.WaitMilliseconds) |
| 464 | } |
| 465 | } |
| 466 | |
| 467 | // If all retries failed for this item |
| 468 | if !itemSuccess { |
| 469 | if bn.ExecItemFallbackFunc != nil { |
| 470 | fallbackResult, fallbackErr := bn.ExecItemFallbackFunc(ctx, bn.params, item, lastItemErr) |
| 471 | if fallbackErr != nil { |
| 472 | // Fallback failed, return error for the whole batch |
| 473 | return nil, newPocketFlowError(fmt.Sprintf("ExecItemFallback failed for item %d (%v) in %T after %d retries", i, item, bn, bn.MaxRetries), fallbackErr) |
| 474 | } |
| 475 | itemResult = fallbackResult // Use fallback result |
| 476 | lastItemErr = nil // Mark as success via fallback |
| 477 | } else { |
| 478 | // No fallback, fail the whole batch |
| 479 | return nil, newPocketFlowError(fmt.Sprintf("ExecItem failed for item %d (%v) in %T after %d retries", i, item, bn, bn.MaxRetries), lastItemErr) |
| 480 | } |
| 481 | } |
| 482 | results[i] = itemResult |
| 483 | } |
| 484 | |
| 485 | return results, nil // Return the slice of results |
| 486 | } |
| 487 | |
| 488 | // Post calls the user-defined PostFunc. |
| 489 | func (bn *BatchNode) Post(ctx *PfContext, prepResult any, execResult any) (string, error) { |
no test coverage detected