Repository navigation
fix(submitqueue): repair terminal request status on retry - #1039
sbalabanov wants to merge 4 commits into
Conversation
Summary: Persist the terminal timestamp, error, and metadata in the winning request snapshot. Retry matching terminal outcomes without another transition or provider call, and prevent incomplete legacy repairs from erasing known diagnostics. Reproduction: 1. Reject or cancel a request while the terminal state write succeeds and its log publication fails. 2. Redeliver the original validation, conflict-signal, or cancellation message. 3. Confirm the retry publishes the original terminal facts without another terminal write; a different terminal winner remains unchanged. Test Plan: The existing Process regression tests exercise failed publication followed by successful replay and compare the original diagnostics, timestamp, and request version. TestTerminateRequest_ReplaysWinningFactsAfterPublishFailure also covers changed retry diagnostics and duplicate delivery. TestRequestTerminalDetailsMigration demonstrates the explicit additive migration, readable legacy NULL details, preserved new diagnostics, and rejection of malformed non-NULL details against MySQL. Materializer tests verify history/mapping repair without overwriting known diagnostics. Verified with ./tool/bazel test //submitqueue/... --test_output=errors (59 targets), the MySQL storage integration target, focused coverage, and repository formatting/lint/module/build/mock checks. Revert Plan: Revert the code while retaining the additive terminal_details column and its persisted facts. Retain failed deliveries for replay; reverting terminal Process repair reopens the missing-log failure.
Summary: Keep terminal-status repair on validation, conflict-signal, and cancellation retries without retaining the original log content. A replay explicitly reports that original terminal details were not retained, preserves the current request version, and uses the same publication identity. Remove the terminal-details entity fields, database schema and migration, storage serialization, gateway legacy protection, and their retention-only tests. Existing termination still publishes the available first-attempt diagnostic; matching-state retries do not repeat the state transition or validation. Test Plan: Six focused request-core and controller targets pass, including the existing three failed-publication/retry regressions. These check status/version stability, explicit unavailable diagnostics, and no repeated state write/provider/validator work. Four affected libraries build; formatting, lint, Gazelle, and module checks pass. Revert Plan: Revert this follow-up commit to restore the original larger draft; reverting the whole PR reopens terminal status repair failures.
| "partition_key", msg.PartitionKey, | ||
| ) | ||
|
|
||
| if request.State == entity.RequestStateCancelled { |
There was a problem hiding this comment.
quick comment why this is necessary, same for other controllers in the change
There was a problem hiding this comment.
[agent-response SQC-009] Added short comments at all three retry guards: a terminal write may succeed before its final log is published. Fixed in 63f2104.
[addressed by agent]
| return corerequest.PublishTerminalRequestLog(ctx, c.registry, request) | ||
| } | ||
|
|
||
| if entity.IsRequestStateTerminal(request.State) { |
There was a problem hiding this comment.
explain why previous new check is not added under this branch
There was a problem hiding this comment.
[agent-response SQC-009] Documented why cancellation only resends Cancelled: other terminal outcomes belong to their winning writer and stay untouched. Fixed in 63f2104.
[addressed by agent]
| "github.com/uber/submitqueue/submitqueue/entity" | ||
| ) | ||
|
|
||
| const terminalDetailsNotRetained = "original terminal details were not retained" |
There was a problem hiding this comment.
no need for a const, embed
also rephrase the error that this is a resend, likely due to consistency, and original error may not be retained
There was a problem hiding this comment.
[agent-response SQC-009] Inlined the diagnostic and identified it as a consistency resend, without claiming that an earlier publication failed or that original details definitely disappeared. Fixed in 63f2104.
[addressed by agent]
|
|
||
| // PublishTerminalRequestLog repairs a terminal request's status without another state write. | ||
| // Original diagnostics are not retained; the repair explicitly reports their absence. | ||
| func PublishTerminalRequestLog(ctx context.Context, registry consumer.TopicRegistry, request entity.Request) error { |
There was a problem hiding this comment.
call it something like "resendTerminalRequestLog" to indicate the usage
There was a problem hiding this comment.
[agent-response SQC-009] Renamed the helper to ResendTerminalRequestLog and updated the callers. The affected child call sites are coordinated and checked before advancing this PR. Fixed in 63f2104.
[addressed by agent]
| func(_ context.Context, topic string, _ entityqueue.Message) error { | ||
| func(_ context.Context, topic string, msg entityqueue.Message) error { | ||
| publishedTopics = append(publishedTopics, topic) | ||
| entry, err := sqmq.UnmarshalRequestLog(msg.Payload) |
There was a problem hiding this comment.
this and other tests: do not modify existing tests and asserts. Try to reduce the amount of code changed in this PR, even if it somewhat sacrifices coverage.
There was a problem hiding this comment.
[agent-response SQC-009] Restored the original controller test assertion bodies and removed the expanded replay scenarios. Only the halted-state fixtures and shared-store expectations required by the new behavior remain changed. Fixed in 63f2104.
[addressed by agent]
Summary: Explain why matching terminal retries resend a status log and why cancellation leaves other terminal outcomes to their winning writer. Name the helper ResendTerminalRequestLog and make its inline diagnostic identify a consistency resend without claiming the original details are definitely lost. Restore the original controller test assertions and remove the expanded replay scenarios. Keep only fixture and shared-store-call expectations required by the changed guards and shared termination path. Test Plan: Six focused core/controller test targets pass; the conflict-signal target also passes after tightening its shared-store expectation. Four affected libraries build, and formatting, lint, Gazelle, and module checks pass. Revert Plan: Revert this follow-up with the dependent helper call-site update to restore the prior exported helper name.
|
|
1 similar comment
|
|
sbalabanov
left a comment
There was a problem hiding this comment.
address comments, republish PR, make it ready for review
| ) | ||
|
|
||
| // ResendTerminalRequestLog resends the request's terminal status without another state write. | ||
| // The log identifies the resend; original diagnostics may be unavailable. |
There was a problem hiding this comment.
Add an example when it can happen that justifies calling this function
There was a problem hiding this comment.
[agent-response SQC-009] Added the concrete validation example in c2484d1: Error can be stored, then the process can crash before publishing its status log. Redelivery resends the status without another request-state write. The update is published and the PR is ready for review after the prescribed readiness gate passed.
[addressed by agent]
Summary: Give the concrete example of validation storing Error and crashing before publishing its status log. Redelivery must resend the status without another request-state write. Test Plan: Comments-only change. Existing request-core unit target passes from cache; repository lint and Gazelle checks pass. No runtime behavior or tests changed. Revert Plan: Revert this comments-only commit.
TL;DR: Rejected or cancelled requests reach their final displayed status even when publishing the terminal log initially fails.
Summary
A rejected or cancelled request can be finished internally but still look unfinished if its final status update fails to send. A retry now resends the final status without repeating validation, cancellation, or a state change. Repairs identify the consistency resend and warn that original details may be unavailable; the first attempt can still include its available reason.
Repro
Test Plan
Six focused core/controller test targets and four affected libraries passed locally; formatting, lint, Gazelle, and module checks passed. No storage integration run is needed: this PR no longer changes storage or schema.
Stack
Based on #1037 (
wt/sqc010); this is the current branch base, not a required runtime dependency.Rollout
No schema migration is required. Replace old consumers so matching terminal retries reach status repair.
Revert Plan
Revert this PR to restore the earlier guard behavior; terminal retries may again leave the displayed status unfinished.
Issue Links
None; repository audit work, no external ticket.