mirror of
https://github.com/ollama/ollama.git
synced 2026-05-13 14:27:00 +00:00
launch/opencode: share one timeout across model capability probes
Avoid paying the full probe timeout once per remembered OpenCode model when rebuilding inline config on launch. Use a single shared timeout context for the entire capability probe pass, so slow or unreachable Show() calls degrade to missing modalities metadata without multiplying startup delay by the number of models. Add a regression test covering the shared-timeout behavior.
This commit is contained in:
parent
49e6507bf4
commit
538d90a896
2 changed files with 52 additions and 10 deletions
|
|
@ -241,19 +241,21 @@ func readModelJSONModels() []string {
|
|||
}
|
||||
|
||||
func buildModelEntries(ctx context.Context, client *api.Client, modelList []string) map[string]any {
|
||||
if client != nil {
|
||||
var cancel context.CancelFunc
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline {
|
||||
ctx, cancel = context.WithTimeout(ctx, openCodeModelShowTimeout)
|
||||
defer cancel()
|
||||
}
|
||||
}
|
||||
|
||||
models := make(map[string]any)
|
||||
for _, modelID := range modelList {
|
||||
entry := map[string]any{
|
||||
"name": modelID,
|
||||
}
|
||||
if client != nil {
|
||||
showCtx := ctx
|
||||
var cancel context.CancelFunc
|
||||
if _, hasDeadline := ctx.Deadline(); !hasDeadline {
|
||||
showCtx, cancel = context.WithTimeout(ctx, openCodeModelShowTimeout)
|
||||
}
|
||||
|
||||
if resp, err := client.Show(showCtx, &api.ShowRequest{Model: modelID}); err == nil {
|
||||
if resp, err := client.Show(ctx, &api.ShowRequest{Model: modelID}); err == nil {
|
||||
if slices.Contains(resp.Capabilities, model.CapabilityVision) {
|
||||
entry["modalities"] = map[string]any{
|
||||
"input": []string{"text", "image"},
|
||||
|
|
@ -261,9 +263,6 @@ func buildModelEntries(ctx context.Context, client *api.Client, modelList []stri
|
|||
}
|
||||
}
|
||||
}
|
||||
if cancel != nil {
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
if isCloudModelName(modelID) {
|
||||
if l, ok := lookupCloudModelLimit(modelID); ok {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ import (
|
|||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ollama/ollama/api"
|
||||
)
|
||||
|
|
@ -222,6 +224,47 @@ func TestBuildModelEntries(t *testing.T) {
|
|||
t.Fatalf("modalities should not be set without an API client, got %v", entry["modalities"])
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("uses one timeout budget across capability probes", func(t *testing.T) {
|
||||
u, err := url.Parse("http://ollama.example")
|
||||
if err != nil {
|
||||
t.Fatalf("parse test URL: %v", err)
|
||||
}
|
||||
|
||||
var mu sync.Mutex
|
||||
waited := 0
|
||||
|
||||
client := api.NewClient(u, &http.Client{Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) {
|
||||
mu.Lock()
|
||||
if req.Context().Err() == nil {
|
||||
waited++
|
||||
}
|
||||
mu.Unlock()
|
||||
|
||||
<-req.Context().Done()
|
||||
return nil, req.Context().Err()
|
||||
})})
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 25*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
models := buildModelEntries(ctx, client, []string{"slow-1", "slow-2"})
|
||||
for _, modelID := range []string{"slow-1", "slow-2"} {
|
||||
entry, _ := models[modelID].(map[string]any)
|
||||
if entry["name"] != modelID {
|
||||
t.Fatalf("name for %q = %v, want %q", modelID, entry["name"], modelID)
|
||||
}
|
||||
if _, ok := entry["modalities"]; ok {
|
||||
t.Fatalf("modalities for %q should not be set after probe timeout, got %v", modelID, entry["modalities"])
|
||||
}
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if waited != 1 {
|
||||
t.Fatalf("expected shared timeout to block one probe, waited on %d probes", waited)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestOpenCodeModels_ReturnsNil(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue