🌐 US-Proxy
class="logged-out env-production page-responsive" style="word-wrap: break-word;" >
Skip to content

fix(coderd): serialize chat model config default election with advisory lock - #27114

Merged
ethanndickson merged 5 commits into
mainfrom
chat-config-hxjn
Jul 14, 2026
Merged

fix(coderd): serialize chat model config default election with advisory lock#27114
ethanndickson merged 5 commits into
mainfrom
chat-config-hxjn

Conversation

@ethanndickson

@ethanndickson ethanndickson commented Jul 9, 2026

Copy link
Copy Markdown
Member

Closes CODAGT-736

Concurrent chat model config writes on a deployment with no default all elect themselves default: at READ COMMITTED neither transaction sees the other's uncommitted default, so both self-promote and idx_chat_model_configs_single_default rejects the loser as a spurious 409. The coderd Terraform provider hits this routinely, since a single terraform apply creates or deletes many configs in parallel by design.

The fix serializes the election with a transaction-scoped advisory lock: the create, update, and delete handlers run their default election inside a transaction that first takes pg_advisory_xact_lock on a dedicated LockIDChatModelConfigDefault, so elections run one at a time and the index is never contended. The partial unique index stays in place as the schema-level invariant, and the existing 409 mapping remains as a backstop for any writer that bypasses the lock.

We considered a singleton pointer table (one row holding a model_config_id FK, making a second default unrepresentable), which would remove the race outright, but it needs a migration, new queries, dbauthz rules, and handler/read-path rework. Not proportionate for an experimental endpoint.

@ethanndickson
ethanndickson marked this pull request as ready for review July 9, 2026 06:22
@ethanndickson ethanndickson changed the title fix(coderd): retry chat model config default election on unique violation fix(coderd): serialize chat model config default election with advisory lock Jul 9, 2026
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 98427ef64e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ethanndickson
ethanndickson requested a review from mafredri July 9, 2026 06:43
@linear-code

linear-code Bot commented Jul 9, 2026

Copy link
Copy Markdown

CODAGT-736

@mafredri mafredri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can the provider be used to choose to promote a model config to default, but during concurrent creation the first non-default creation that acquires the lock promotes itself resulting in an error creating the one we want as default?

Comment thread coderd/exp_chats.go Outdated
…ry lock

Replaces the unique-violation retry loop: the election transactions now
take pg_advisory_xact_lock(LockIDChatModelConfigDefault) so only one
election runs at a time and the single-default index is never contended.
The index and the 409 mapping stay as the schema-level backstop.
Comment thread coderd/exp_chats.go Outdated
@ethanndickson
ethanndickson merged commit 535c775 into main Jul 14, 2026
28 of 29 checks passed
@ethanndickson
ethanndickson deleted the chat-config-hxjn branch July 14, 2026 03:51
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 14, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants