Rename to gpu-turnstile; swap port roles
The proxy now listens on the standard service ports (Ollama :11434, ComfyUI :8188) and the actual services move one port up (:11435, :8189). Metric prefix is now gpu_turnstile_.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// Package comfy is a minimal client for the ComfyUI endpoints gpulock needs
|
||||
// after a prompt has been accepted: polling /history and freeing VRAM.
|
||||
// Package comfy is a minimal client for the ComfyUI endpoints gpu-turnstile
|
||||
// needs after a prompt has been accepted: polling /history and freeing VRAM.
|
||||
package comfy
|
||||
|
||||
import (
|
||||
|
||||
+21
-21
@@ -1,4 +1,4 @@
|
||||
// Package metrics provides the Prometheus text exposition for gpulock
|
||||
// Package metrics provides the Prometheus text exposition for gpu-turnstile
|
||||
// without any external dependencies.
|
||||
package metrics
|
||||
|
||||
@@ -51,7 +51,7 @@ func trimLabel(label string) string {
|
||||
return label
|
||||
}
|
||||
|
||||
// Metrics holds all gpulock metric values.
|
||||
// Metrics holds all gpu-turnstile metric values.
|
||||
type Metrics struct {
|
||||
llmWait *histogram
|
||||
imageWait *histogram
|
||||
@@ -86,36 +86,36 @@ func (m *Metrics) IncImageJobs() { m.imageJobs.Add(1) }
|
||||
|
||||
// Render writes the Prometheus text exposition for the given lock snapshot.
|
||||
func (m *Metrics) Render(w io.Writer, state string, llmInflight int, imagePending bool) {
|
||||
fmt.Fprint(w, `# HELP gpulock_state Current GPU state (1 for the active state).
|
||||
# TYPE gpulock_state gauge
|
||||
fmt.Fprint(w, `# HELP gpu_turnstile_state Current GPU state (1 for the active state).
|
||||
# TYPE gpu_turnstile_state gauge
|
||||
`)
|
||||
for _, s := range []string{"idle", "llm", "image"} {
|
||||
v := 0
|
||||
if s == state {
|
||||
v = 1
|
||||
}
|
||||
fmt.Fprintf(w, "gpulock_state{state=%q} %d\n", s, v)
|
||||
fmt.Fprintf(w, "gpu_turnstile_state{state=%q} %d\n", s, v)
|
||||
}
|
||||
pending := 0
|
||||
if imagePending {
|
||||
pending = 1
|
||||
}
|
||||
fmt.Fprintf(w, `# HELP gpulock_llm_inflight LLM requests currently in flight.
|
||||
# TYPE gpulock_llm_inflight gauge
|
||||
gpulock_llm_inflight %d
|
||||
# HELP gpulock_image_pending Whether an image job is active or waiting.
|
||||
# TYPE gpulock_image_pending gauge
|
||||
gpulock_image_pending %d
|
||||
# HELP gpulock_image_jobs_total Image jobs accepted by ComfyUI.
|
||||
# TYPE gpulock_image_jobs_total counter
|
||||
gpulock_image_jobs_total %d
|
||||
# HELP gpulock_lock_wait_seconds Time spent waiting to acquire the GPU lock.
|
||||
# TYPE gpulock_lock_wait_seconds histogram
|
||||
fmt.Fprintf(w, `# HELP gpu_turnstile_llm_inflight LLM requests currently in flight.
|
||||
# TYPE gpu_turnstile_llm_inflight gauge
|
||||
gpu_turnstile_llm_inflight %d
|
||||
# HELP gpu_turnstile_image_pending Whether an image job is active or waiting.
|
||||
# TYPE gpu_turnstile_image_pending gauge
|
||||
gpu_turnstile_image_pending %d
|
||||
# HELP gpu_turnstile_image_jobs_total Image jobs accepted by ComfyUI.
|
||||
# TYPE gpu_turnstile_image_jobs_total counter
|
||||
gpu_turnstile_image_jobs_total %d
|
||||
# HELP gpu_turnstile_lock_wait_seconds Time spent waiting to acquire the GPU lock.
|
||||
# TYPE gpu_turnstile_lock_wait_seconds histogram
|
||||
`, llmInflight, pending, m.imageJobs.Load())
|
||||
m.llmWait.write(w, "gpulock_lock_wait_seconds", `kind="llm",`)
|
||||
m.imageWait.write(w, "gpulock_lock_wait_seconds", `kind="image",`)
|
||||
fmt.Fprint(w, `# HELP gpulock_unload_seconds Time spent unloading Ollama models before an image job.
|
||||
# TYPE gpulock_unload_seconds histogram
|
||||
m.llmWait.write(w, "gpu_turnstile_lock_wait_seconds", `kind="llm",`)
|
||||
m.imageWait.write(w, "gpu_turnstile_lock_wait_seconds", `kind="image",`)
|
||||
fmt.Fprint(w, `# HELP gpu_turnstile_unload_seconds Time spent unloading Ollama models before an image job.
|
||||
# TYPE gpu_turnstile_unload_seconds histogram
|
||||
`)
|
||||
m.unload.write(w, "gpulock_unload_seconds", "")
|
||||
m.unload.write(w, "gpu_turnstile_unload_seconds", "")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Package ollama is a minimal client for the Ollama management endpoints
|
||||
// gpulock needs: listing loaded models, unloading them, and warming a model.
|
||||
// gpu-turnstile needs: listing loaded models, unloading them, and warming a
|
||||
// model.
|
||||
package ollama
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package proxy contains the HTTP handlers for both gpulock listeners:
|
||||
// Package proxy contains the HTTP handlers for both gpu-turnstile listeners:
|
||||
// reverse proxies to Ollama and ComfyUI with GPU lock arbitration in front
|
||||
// of the endpoints that load models.
|
||||
package proxy
|
||||
@@ -43,7 +43,7 @@ type Config struct {
|
||||
WarmModel string
|
||||
}
|
||||
|
||||
// Server serves both gpulock listeners.
|
||||
// Server serves both gpu-turnstile listeners.
|
||||
type Server struct {
|
||||
cfg Config
|
||||
log *slog.Logger
|
||||
|
||||
@@ -40,13 +40,13 @@ func (r *recorder) index(e string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// fakes wires up fake Ollama and ComfyUI upstreams plus the gpulock server.
|
||||
// fakes wires up fake Ollama and ComfyUI upstreams plus the gpu-turnstile server.
|
||||
type fakes struct {
|
||||
rec *recorder
|
||||
ollama *httptest.Server
|
||||
comfy *httptest.Server
|
||||
server *httptest.Server // Ollama-facing gpulock listener
|
||||
comfySrv *httptest.Server // ComfyUI-facing gpulock listener
|
||||
server *httptest.Server // Ollama-facing gpu-turnstile listener
|
||||
comfySrv *httptest.Server // ComfyUI-facing gpu-turnstile listener
|
||||
freeCh chan struct{}
|
||||
chatCh chan struct{}
|
||||
historyMu sync.Mutex
|
||||
@@ -279,7 +279,7 @@ func TestStreamingNotBuffered(t *testing.T) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// If gpulock buffered the stream, this read would never complete while
|
||||
// If gpu-turnstile buffered the stream, this read would never complete while
|
||||
// the gate is closed.
|
||||
line, err := bufio.NewReader(resp.Body).ReadString('\n')
|
||||
if err != nil {
|
||||
@@ -321,11 +321,11 @@ func TestHealthzAndMetrics(t *testing.T) {
|
||||
resp.Body.Close()
|
||||
text := string(body)
|
||||
for _, want := range []string{
|
||||
`gpulock_state{state="idle"} 1`,
|
||||
"gpulock_llm_inflight 0",
|
||||
"gpulock_image_jobs_total 0",
|
||||
`gpulock_lock_wait_seconds_bucket{kind="llm",le="+Inf"} 0`,
|
||||
"gpulock_unload_seconds_count{} 0",
|
||||
`gpu_turnstile_state{state="idle"} 1`,
|
||||
"gpu_turnstile_llm_inflight 0",
|
||||
"gpu_turnstile_image_jobs_total 0",
|
||||
`gpu_turnstile_lock_wait_seconds_bucket{kind="llm",le="+Inf"} 0`,
|
||||
"gpu_turnstile_unload_seconds_count{} 0",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("metrics missing %q", want)
|
||||
|
||||
Reference in New Issue
Block a user