Skip to content

Thread context.Context through modelsdev store API#1747

Merged
dgageot merged 1 commit intodocker:mainfrom
rumpl:context
Feb 16, 2026
Merged

Thread context.Context through modelsdev store API#1747
dgageot merged 1 commit intodocker:mainfrom
rumpl:context

Conversation

@rumpl
Copy link
Member

@rumpl rumpl commented Feb 16, 2026

Pass caller-provided context to the HTTP request in fetchFromAPI instead of using context.Background(). This allows cancellation and deadline propagation when fetching from the models.dev API.

Updated all public Store methods (GetDatabase, GetProvider, GetModel, ResolveModelAlias) and ModelSupportsReasoning to accept context. Changed the lazy loading from sync.OnceValues to sync.Once to support the context parameter. Updated all callsites across the codebase, using context.Background() only in TUI callbacks and pricing calculation callbacks where no caller context is available.

Assisted-By: cagent

@rumpl rumpl requested a review from a team as a code owner February 16, 2026 09:44
docker-agent[bot]

This comment was marked as resolved.

@docker docker deleted a comment from docker-agent bot Feb 16, 2026
@rumpl
Copy link
Member Author

rumpl commented Feb 16, 2026

/review

Copy link

@docker-agent docker-agent bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Found 2 HIGH severity race condition bugs introduced by removing sync.OnceValues without replacement synchronization.

The Store type documents "All methods are safe for concurrent use" but the new GetDatabase() implementation lacks synchronization primitives (no mutex, no sync.Once). Multiple concurrent calls can:

  1. Both pass the nil check and call loadDatabase() simultaneously (wasting API calls)
  2. Both write to s.db, creating a data race

Additionally, there's a blocking network call in the TUI event loop that can freeze the UI for up to 30 seconds.

Critical: These bugs will cause data races and UI freezes under concurrent usage.

Replace the lazy-loaded closure-based Store with a simple struct
that holds a cache file path and loads the database on first
GetDatabase call. Pass caller-provided context to the HTTP request
in fetchFromAPI instead of using context.Background().

NewStore() remains context-free (no I/O). All Store methods
(GetDatabase, GetProvider, GetModel, ResolveModelAlias) and
ModelSupportsReasoning accept context for the network call.
Updated all callsites, using context.Background() only in TUI
callbacks where no caller context is available.

Assisted-By: cagent
@rumpl
Copy link
Member Author

rumpl commented Feb 16, 2026

/review

Copy link

@docker-agent docker-agent bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Found 3 high severity and 2 medium severity concurrency/context issues in the changed code. The most critical issues are:

  1. Mutex held during blocking network I/O - Can freeze all concurrent requests for up to 30s
  2. UI event handlers block with context.TODO() - Acknowledged by TODOs in the code, will freeze TUI
  3. context.Background() in cost calculations - Cannot respect cancellation

The high severity issues should be addressed before merging as they can cause significant user-facing freezes.

@dgageot dgageot merged commit 75d32dc into docker:main Feb 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants