Documentation
¶
Overview ¶
Package executor implements job execution orchestration.
This package provides the Executor service that coordinates the complete job execution lifecycle: job discovery, plan generation, image validation, stack stop, worker execution, and stack restart.
Execution Flow ¶
- Discover job by name (via JobDiscoverer port)
- Generate execution plan (via JobPlanner port)
- Pre-validate worker image exists (fail fast)
- Stop target Compose stack (via ComposeController port)
- Run worker container (via WorkerRunner port)
- Restart stack (ALWAYS, even on worker failure)
Guaranteed Restart ¶
The executor uses defer to ensure that the Compose stack is restarted even if:
- Worker fails with non-zero exit code
- Worker times out
- Execution is interrupted (Ctrl+C)
- Context is cancelled
This design prevents leaving production stacks in a stopped state.
Error Handling ¶
- Pre-validation failure: Return error, stack NOT stopped
- Stop failure: Return error, stack may be partially stopped
- Worker failure: Restart stack, return WorkerError
- Start failure: Return error, stack may be partially started
Signal Handling ¶
The executor respects context cancellation (e.g., Ctrl+C). When cancelled:
- In-flight operations are cancelled
- Worker is stopped (SIGTERM → SIGKILL)
- Stack is restarted (best effort)
- ExecutionResult reflects cancellation
References ¶
- GitHub Issue: #121
- Port Interface: internal/ports/executor.go (#114)
- Research: .serena/memories/m3_failure_handling.md
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor orchestrates job execution.
func New ¶
func New( planner ports.JobPlanner, compose ports.ComposeController, worker ports.WorkerRunner, docker *client.Client, ) *Executor
New creates a new Executor with dependency injection.
func (*Executor) DryRun ¶
DryRun returns the execution plan without executing (implements ports.JobExecutor).
func (*Executor) Execute ¶
func (e *Executor) Execute(ctx context.Context, job jobs.Job, opts ports.ExecuteOptions) (ports.ExecutionResult, error)
Execute runs a job (implements ports.JobExecutor). Implements the step interpreter pattern: the executor iterates over plan.Steps and executes each step based on its type. This ensures plan-is-source-of-truth.