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.
52 lines
1.0 KiB
Go
52 lines
1.0 KiB
Go
package lock
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestTryAcquireLLM(t *testing.T) {
|
|
lk := New(nil)
|
|
if !lk.TryAcquireLLM() {
|
|
t.Fatal("TryAcquireLLM on idle lock should succeed")
|
|
}
|
|
if _, n, _ := lk.Snapshot(); n != 1 {
|
|
t.Fatalf("n = %d, want 1", n)
|
|
}
|
|
|
|
// While an image job is pending, TryAcquireLLM must fail.
|
|
imageWaiting := make(chan struct{})
|
|
go func() {
|
|
lk.AcquireImage(context.Background())
|
|
close(imageWaiting)
|
|
}()
|
|
deadline := time.Now().Add(2 * time.Second)
|
|
for {
|
|
lk.mu.Lock()
|
|
queued := len(lk.imageQ)
|
|
lk.mu.Unlock()
|
|
if queued == 1 {
|
|
break
|
|
}
|
|
if time.Now().After(deadline) {
|
|
t.Fatal("image waiter never queued")
|
|
}
|
|
time.Sleep(time.Millisecond)
|
|
}
|
|
if lk.TryAcquireLLM() {
|
|
t.Fatal("TryAcquireLLM with image pending should fail")
|
|
}
|
|
|
|
lk.ReleaseLLM()
|
|
<-imageWaiting
|
|
if lk.TryAcquireLLM() {
|
|
t.Fatal("TryAcquireLLM with image active should fail")
|
|
}
|
|
lk.ReleaseImage()
|
|
if !lk.TryAcquireLLM() {
|
|
t.Fatal("TryAcquireLLM after image release should succeed")
|
|
}
|
|
lk.ReleaseLLM()
|
|
}
|