Repository navigation
Conversation
…eue request status vocabulary
…the queue_request_status table
…r on every log delivery and enable records in the reference server
…records in the storage contracts
…p records on terminal statuses, and skip event logs
…atuses so the in-queue list lives in one place
… and that readers must confirm and clean them up
roychying
force-pushed
the
chenghan.ying/sqv2-gateway-request-status
branch
from
October 20, 2026 18:39
ccb6d37 to
08996ad
Compare
roychying
changed the base branch from
chenghan.ying/sqv2-dashboard-metrics
to
main
October 20, 2026 18:39
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why?
The SQv2 dashboard needs queue depth: how many requests each queue holds at each status right now, and how long the oldest has been waiting. Nothing answers "requests of queue Q at status S" today.
request_summaryonly supports reads by request ID, a(queue, status)index would break the key-value storage contract, and scanning a queue's summaries reads its whole history.This replaces #891, which kept these records in the orchestrator. The gateway is the better home, as discussed on #891:
request.state: it showsvalidating,batching,speculatingandlanding, where the orchestrator staysbatchedfrom batching through landing.received_at_ms, so age since submit is available.What?
Entity:
QueueRequestStatus{Queue, Status, RequestID, ReceivedAtMs, EnteredAtMs}, plusInQueueRequestStatuses(), the one list of in-queue statuses (every public status exceptacceptingand the terminal statuses);IsRequestStatusInQueuederives from it.Store contract:
QueueRequestStatusStorewithList(status),Put,Delete. Same advisory, per-record pattern asQueueBatchStateStore: single-key idempotent writes, no multi-row transactions.MySQL: gateway
queue_request_statustable, PK(queue, status, request_id), so listing by status is a primary-key prefix scan.PutisINSERT … ON DUPLICATE KEY UPDATE entered_at_ms = entered_at_ms, so re-filing keeps the original entry time.Opt-in:
mysql.NewStorage(db, scope, WithQueueRequestStatusRecords()). Without it, record writes are no-ops andListreturns an error, so a bump can't write to a table the deployment doesn't have yet. The reference gateway server enables it.Materializer: on every status-log delivery, after the summary update,
PersistLogkeeps the record in step with the summary:acceptingand terminal statuses have no record. Event logs never move the summary, so they skip the record.Records are advisory, and stale rows happen in normal operation. Land and Cancel persist logs outside the log consumer's per-request ordering, and a delivery whose lease expires can overlap its redelivery. In each case a late
Putcan re-file a status another writer already moved the summary away from. The re-read after each put removes those, because every writer updates the summary before deleting the old record. The terminal sweep covers finished requests. A record stranded by a failed move while the request is still in the queue remains until the request finishes. So readers must confirm each listed request against its summary, count it only under the summary's status, and delete rows whose summary is finished or at a different status. That's one summary read per listed row per reader per sample.request_summarystays the only source of truth.Docs: gateway schema README (new section, including the stale-row rules and reader cleanup), the store contract and entity docs, storage README key-value contract,
AGENTS.mdand the service-scoped RFC (fourteen store contracts, five gateway accessors).Test Plan
acceptingor unknown); MySQL store list/put/delete including queue mismatch and no-op cases; the storage option off and on.accepting, put and delete failures returned for retry.TestStorage_QueueRequestStatusRecordLifecycleagainst real MySQL (runs in CI): bucket listing, re-put keeps the firstentered_at_ms, moves, queue isolation.make lint(queue-shard linter: all 33 tables shardable),check-gazelle,check-tidy,check-mocks.Issue