Add LLM busy modes: wait (hang) or reject with Retry-After
LLM_BUSY_MODE=reject answers blocked LLM requests immediately with LLM_BUSY_STATUS (default 503, 429 works) and Retry-After, so routers like LiteLLM can cool down and retry instead of holding a hung connection. The default wait mode now also sends Retry-After when LLM_WAIT_TIMEOUT expires. Document the service account (LocalSystem default, NT SERVICE virtual-account hardening) and the Program Files / ProgramData install layout.
This commit is contained in:
@@ -37,6 +37,13 @@ type Config struct {
|
||||
UpdateRepo string
|
||||
UpdateAsset string
|
||||
|
||||
// LLMBusyMode is "wait" (hold requests until the lock is free or
|
||||
// LLMWaitTimeout expires) or "reject" (immediately answer with
|
||||
// LLMBusyStatus + Retry-After when an image job is active or pending).
|
||||
LLMBusyMode string
|
||||
LLMBusyStatus int
|
||||
BusyRetryAfter int
|
||||
|
||||
WarmModel string
|
||||
LogLevel slog.Level
|
||||
LogJSON bool
|
||||
@@ -70,6 +77,10 @@ func Defaults() Config {
|
||||
UpdateRepo: "https://git.rambossek.at/PUBLIC/gpu-turnstile",
|
||||
UpdateAsset: "gpu-turnstile.exe",
|
||||
|
||||
LLMBusyMode: "wait",
|
||||
LLMBusyStatus: 503,
|
||||
BusyRetryAfter: 30,
|
||||
|
||||
LogLevel: slog.LevelWarn,
|
||||
}
|
||||
}
|
||||
@@ -169,6 +180,26 @@ func Load(getenv func(string) string) (Config, error) {
|
||||
}
|
||||
cfg.AutoUpdate = b
|
||||
}
|
||||
if v := getenv("LLM_BUSY_MODE"); v != "" {
|
||||
if v != "wait" && v != "reject" {
|
||||
return cfg, fmt.Errorf("LLM_BUSY_MODE: must be \"wait\" or \"reject\"")
|
||||
}
|
||||
cfg.LLMBusyMode = v
|
||||
}
|
||||
if v := getenv("LLM_BUSY_STATUS"); v != "" {
|
||||
n, err := strconv.Atoi(v)
|
||||
if err != nil || n < 400 || n > 599 {
|
||||
return cfg, fmt.Errorf("LLM_BUSY_STATUS: must be an HTTP status in 400-599")
|
||||
}
|
||||
cfg.LLMBusyStatus = n
|
||||
}
|
||||
if v := getenv("BUSY_RETRY_AFTER"); v != "" {
|
||||
n, err := strconv.Atoi(v)
|
||||
if err != nil || n <= 0 {
|
||||
return cfg, fmt.Errorf("BUSY_RETRY_AFTER: must be a positive integer (seconds)")
|
||||
}
|
||||
cfg.BusyRetryAfter = n
|
||||
}
|
||||
// LOGLEVEL is the canonical spelling; LOG_LEVEL is kept as an alias.
|
||||
logLevelValue := getenv("LOGLEVEL")
|
||||
if logLevelValue == "" {
|
||||
|
||||
@@ -83,6 +83,9 @@ func TestLoadErrors(t *testing.T) {
|
||||
{"AUTO_UPDATE", "maybe"},
|
||||
{"LOGLEVEL", "shouty"},
|
||||
{"LOG_FORMAT", "yaml"},
|
||||
{"LLM_BUSY_MODE", "bogus"},
|
||||
{"LLM_BUSY_STATUS", "200"},
|
||||
{"BUSY_RETRY_AFTER", "0"},
|
||||
} {
|
||||
_, err := Load(func(k string) string {
|
||||
if k == tc.key {
|
||||
|
||||
Reference in New Issue
Block a user