summaryrefslogtreecommitdiff
path: root/internal/executor/executor.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/executor/executor.go')
-rw-r--r--internal/executor/executor.go18
1 files changed, 18 insertions, 0 deletions
diff --git a/internal/executor/executor.go b/internal/executor/executor.go
index 51f468e..eb23c02 100644
--- a/internal/executor/executor.go
+++ b/internal/executor/executor.go
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
+ "path/filepath"
"sync"
"time"
@@ -12,6 +13,13 @@ import (
"github.com/google/uuid"
)
+// LogPather is an optional interface runners can implement to provide the log
+// directory for an execution before it starts. The pool uses this to persist
+// log paths at CreateExecution time rather than waiting until execution ends.
+type LogPather interface {
+ ExecLogDir(execID string) string
+}
+
// Runner executes a single task and returns the result.
type Runner interface {
Run(ctx context.Context, t *task.Task, exec *storage.Execution) error
@@ -115,6 +123,16 @@ func (p *Pool) execute(ctx context.Context, t *task.Task) {
Status: "RUNNING",
}
+ // Pre-populate log paths so they're available in the DB immediately —
+ // before the subprocess starts — enabling live tailing and debugging.
+ if lp, ok := p.runner.(LogPather); ok {
+ if logDir := lp.ExecLogDir(execID); logDir != "" {
+ exec.StdoutPath = filepath.Join(logDir, "stdout.log")
+ exec.StderrPath = filepath.Join(logDir, "stderr.log")
+ exec.ArtifactDir = logDir
+ }
+ }
+
// Record execution start.
if err := p.store.CreateExecution(exec); err != nil {
p.logger.Error("failed to create execution record", "error", err)