feat(config): add GOCLAW_CRON_JOB_TIMEOUT env var for cron timeout (#1099)

Allow overriding the cron job execution timeout via env var, matching
the existing GOCLAW_* env var pattern used throughout the codebase.

Falls back to the existing default (10m) when unset or invalid, since
CronConfig.JobTimeoutDuration() already handles parse errors with a
slog.Warn and the DefaultJobTimeout constant.

Co-authored-by: will.nguyen <will.nguyen@gemcommerce.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-06-23 03:08:44 +07:00
1 parent 9ec542251d
commit 6d742d4153
2 files changed
+56

No files matched your search

+3
View File
@@ -379,6 +379,9 @@ func (c *Config) applyEnvOverrides() {
if c.Tools.Browser.RemoteURL != "" {
c.Tools.Browser.Enabled = true
}
// Cron job execution
envStr("GOCLAW_CRON_JOB_TIMEOUT", &c.Cron.JobTimeout)
}
// Save writes the config to a JSON file.
+53
View File
@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"testing"
"time"
)
// --- Default ---
@@ -429,3 +430,55 @@ func TestLoad_OwnerIDsEmpty(t *testing.T) {
}
}
}
// --- Cron job timeout env override ---
func TestLoad_CronJobTimeout_EnvVar(t *testing.T) {
t.Setenv("GOCLAW_CRON_JOB_TIMEOUT", "1h")
cfg, err := Load("/nonexistent/path")
if err != nil {
t.Fatalf("load error: %v", err)
}
if got := cfg.Cron.JobTimeoutDuration(); got != time.Hour {
t.Fatalf("cron timeout: got %v, want 1h", got)
}
}
func TestLoad_CronJobTimeout_Invalid_FallsBackToDefault(t *testing.T) {
t.Setenv("GOCLAW_CRON_JOB_TIMEOUT", "not-a-duration")
cfg, err := Load("/nonexistent/path")
if err != nil {
t.Fatalf("load error: %v", err)
}
if got := cfg.Cron.JobTimeoutDuration(); got != DefaultJobTimeout {
t.Fatalf("invalid duration should fall back to default %v, got %v", DefaultJobTimeout, got)
}
}
func TestLoad_CronJobTimeout_Unset_UsesDefault(t *testing.T) {
cfg, err := Load("/nonexistent/path")
if err != nil {
t.Fatalf("load error: %v", err)
}
if got := cfg.Cron.JobTimeoutDuration(); got != DefaultJobTimeout {
t.Fatalf("unset env should use default %v, got %v", DefaultJobTimeout, got)
}
}
func TestLoad_CronJobTimeout_EnvOverridesFile(t *testing.T) {
dir := t.TempDir()
cfgPath := filepath.Join(dir, "config.json5")
os.WriteFile(cfgPath, []byte(`{"cron":{"job_timeout":"5m"}}`), 0644)
t.Setenv("GOCLAW_CRON_JOB_TIMEOUT", "30m")
cfg, err := Load(cfgPath)
if err != nil {
t.Fatalf("load error: %v", err)
}
if got := cfg.Cron.JobTimeoutDuration(); got != 30*time.Minute {
t.Fatalf("env should override file: got %v, want 30m", got)
}
}