Tags: uber/submitqueue
Tags
fix(consumer): derive controllerCtx from Background, not caller conte… …xt (#368) ## Summary - `consumer.subscribe` created `controllerCtx` from the caller's `ctx`, which inherits any deadline (e.g. Fx `OnStart`'s 15-second timeout). The consume loop selects on `controllerCtx.Done()` and exits when the deadline fires, silently dropping all subsequent messages. - The subscriber already uses `context.Background()`; this aligns the consumer to match. `Stop()` is the shutdown mechanism, not caller context cancellation. ## Test plan - [x] New test `TestConsumer_ConsumeLoopSurvivesCallerDeadline`: starts the consumer with a 50ms deadline context, waits for expiry, delivers a message, asserts it is processed - [x] All existing consumer tests pass
Changing noisy logs to debug level (#373) ## Summary Moving a couple noisy logs from info to debug level ## Test Plan ## Issues
feat(stovepipe): publish admitted requests to build (#364) ## What - Add the internal id-only BuildRequest contract and build topic. - Publish admitted requests from process and re-publish processing requests to recover missed handoffs. - Register the publish-only build topic and cover handoff/recovery failures. ## Why The upcoming build stage needs an idempotent handoff after process commits the immutable strategy and baseline. ## Test plan - [x] `./tool/bazel test //stovepipe/controller/process:go_default_test //stovepipe/core/messagequeue:go_default_test //service/stovepipe/server:go_default_library` - [x] `make proto && make gazelle`
feat(stovepipe): derive build strategy in process step (#358) ## What? - Add source-control-backed build-strategy selection to Stovepipe’s process stage. - Pin admitted requests to an incremental last-green baseline when ancestry is valid; otherwise use a full build. - Fall back safely to full builds when the baseline is unavailable, and return unexpected source-control errors for normal consumer handling. - Add coverage for cold starts, rewrites, unavailable ancestry, failures, and queue CAS reloads. ## Why? Implementing proposed strategy selection from https://github.com/uber/submitqueue/blob/main/doc/rfc/stovepipe/steps/process.md ## Test Plan Incremental: - Seed an existing queue value in the DB matching the fake source control head - call uber.submitqueue.stovepipe.Stovepipe/Ingest - Check request in DB: ``` state: processing build_strategy: incremental_since_green base_uri: git://manual/incremental/HEAD ``` New Request: - Empty/fresh DB - call uber.submitqueue.stovepipe.Stovepipe/Ingest - Check request in DB ``` state: processing build_strategy: full base_uri: <blank> ``` Not an Ancestor - Seed an existing queue value in the DB that does not match the fake source control (so ancestor check returns false) - Empty/fresh DB - call uber.submitqueue.stovepipe.Stovepipe/Ingest - Check request in DB ``` state: processing build_strategy: full base_uri: <blank> ``` - Planning some more integration tests around this flow
feat(stovepipe): add Build entity and terminal Request states (#362) ## Why? Stovepipe's `build`/`buildsignal` pipeline stage needs a `Build` entity to track a triggered build's lifecycle, and `buildsignal`/DLQ reconciliation need a way to know when a `Request` has reached a state the pipeline will never advance past. ## What? - Adds `stovepipe/entity/build.go`: - `BuildStatus` (accepted/running/succeeded/failed/cancelled) with `IsTerminal()` — shaped like SubmitQueue's `BuildStatus` but defined locally rather than shared. - `Build` — a single triggered build (ID, RequestID, URI, BaseURI, Status, Version), immutable except `Status`/`Version`, which only `buildsignal` writes after `build` creates the row. - `BuildID` — a lightweight wrapper for the runner-assigned id, used on the queue and as the `BuildRunner` Status/Cancel parameter. - `BuildMetadata` — caller-supplied, provider-echoed free-form metadata (empty for now). - JSON (de)serialization helpers (`ToBytes`/`*FromBytes`) for queue payloads on all three types. - Extends `stovepipe/entity/request.go`: - Two new `RequestState` values: `recorded_green` / `recorded_not_green`, written by `record`. once whole-repo greenness is written for a URI (normal path or fail-closed reconciler). - `RequestState.IsTerminal()` — true for `superseded` or either recorded outcome — used by `buildsignal` to short-circuit polling once a Request is already done. ## Test Plan `go test ./stovepipe/...` passes locally. Need to conduct e2e testing after filling in more logics. ## Issue <!-- Link the issue here. - Use 'Closes #123' if this is the final fix. - Use 'Part of #123' or just '#123' if the feature is still in progress. --> Co-authored-by: chenghan.ying <chenghan.ying@uber.com>
refactor(stovepipe): make IngestController operate on entities (#361) ## Summary Remove proto coupling from IngestController.Ingest by changing its signature to accept entity.IngestRequest and return entity.IngestResult directly. Add mapper.ProtoToIngestRequest and mapper.IngestResultToProto in the mapper subpackage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ## Test Plan Unit tests ## Issues ## Stack 1. #359 1. #360 1. #363 1. @ #361 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
refactor(gateway): make StatusController operate on entities (#363) ## Summary Remove proto coupling from StatusController.Status by changing its signature to accept entity.StatusRequest and return request.CurrentState directly. Add mapper.ProtoToStatusRequest and mapper.CurrentStateToProto in the mapper subpackage. The Status mapper is the first with a non-trivial entity-to-proto direction (translating the CurrentState read model into pb.StatusResponse). Add entity.StatusRequest{ID} for input consistency with the other controllers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ## Test Plan ## Issues ## Stack 1. #359 1. #360 1. @ #363 1. #361 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
refactor(gateway): make CancelController operate on entities (#360) ## Summary Remove proto coupling from CancelController.Cancel by changing its signature from (*pb.CancelRequest) (*pb.CancelResponse, error) to (entity.CancelRequest) error. The empty CancelResponse is now constructed at the handler layer. Add mapper.ProtoToCancelRequest in the mapper subpackage and wire it through GatewayServer.Cancel. Rename entity/cancel_request.go to entity/cancel.go for consistency with entity/land.go. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ## Test Plan ## Issues ## Stack 1. #359 1. @ #360 1. #363 1. #361 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
refactor(gateway): make LandController operate on entities (#359) ## Summary Move proto<->entity translation out of the gateway Land controller and into a dedicated mapper package. The controller now takes entity.LandRequest and returns entity.LandResult, keeping business logic proto-free; the GatewayServer adapter maps the wire request in and the response out. - add entity.LandResult; consolidate LandRequest/LandResult into entity/land.go - add service/.../server/mapper with ProtoToLandRequest + strategy resolution - keep field validation in the controller so it runs on controller-to-controller calls Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> ## Test Plan ## Issues ## Stack 1. @ #359 1. #360 1. #363 1. #361 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(submitqueue): keep internal merge stage topic distinct from runwa… …y merge queue The orchestrator registers its internal merge pipeline stage and the runway-owned merge queue in one topic registry over one shared queue backend, and both used the topic key "merge" (topickey.TopicKeyMerge == runwaymq.TopicKeyMerge). The publish-only runway entry silently shadowed the internal stage entry (last write wins), collapsing the two topics into one: - runway consumed the internal batch-ID messages as zero-step MergeRequests and reported SUCCEEDED without ever seeing the real steps; - the orchestrator merge controller's real MergeRequest publish was then silently dropped by the queue's (topic, partition_key, id) dedupe, because it reuses the batch ID already published to the same topic. The pipeline still reached "landed" only because the zero-step result correlates by batch ID — with a real merger nothing would ever have been merged. Found by the e2e harness asserting runway's merge signal carries the request's step IDs. Namespace the merge topic keys by owner so the two can never collide: the runway-owned queue becomes "runway-merge" and the internal orchestrator stage becomes "submitqueue-merge" (both key and wire name). Also make consumer.NewTopicRegistry reject duplicate topic keys so a future collision fails at startup instead of silently misrouting messages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PreviousNext