You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(runway): collapse orchestrator into single-service domain (#272)
## Summary
### Why?
Runway only ever had a single service, so the per-domain `gateway/` +
`orchestrator/` split wrapped it in an empty service layer. Making the
runway domain *be* the service removes that indirection and matches how
runway actually works — a consumer-only landing service with no gateway.
### What?
Collapses the `orchestrator` service segment out of the runway domain:
- `runway/orchestrator/controller/*` → `runway/controller/*`
- `api/runway/orchestrator/{proto,protopb}` →
`api/runway/{proto,protopb}`
- `example/runway/orchestrator/{client,server}` →
`example/runway/{client,server}`
The proto package becomes `uber.runway` (was `uber.runway.orchestrator`)
and the RPC service `RunwayOrchestrator` becomes `Runway`. Server/client
identifiers, metric scope, and the `ServiceName` ping field follow suit.
Build tooling (`tool/proto`, `Makefile` targets, `docker-compose.yml`,
`Dockerfile`) and docs (`CLAUDE.md`, `runway/README.md`, runway workflow
RFC) are updated, documenting the single-service-domain pattern.
## Test Plan
- ✅ `make build`
- ✅ `make proto` + `make gazelle` (idempotent)
- ✅ runway tests: `//runway/...`, `//api/runway/...`,
`//example/runway/...`
Co-authored-by: Cursor <cursoragent@cursor.com>
│ └── testutil/ # Test utilities (ComposeStack, MySQL helpers)
63
67
└── doc/ # Documentation
64
68
```
65
69
66
-
The `platform/` tree holds code reused across domains (infrastructure, shared entities, shared extension contracts). Each **domain** (`submitqueue/`, `stovepipe/`, …) grows into the same internal layout (`gateway/`, `orchestrator/`, `entity/`, `extension/`, `core/`); a domain's own `core/` (e.g. `submitqueue/core/`) holds infra shared only between that domain's services. A domain may start smaller — Stovepipe is currently a single Ping-only service with just `controller/` (and a service-segment-free `api/stovepipe/`), adding the other layers as it gains real behavior.
70
+
The `platform/` tree holds code reused across domains (infrastructure, shared entities, shared extension contracts). A multi-service **domain** (e.g. `submitqueue/`) keeps the same internal layout (`gateway/`, `orchestrator/`, `entity/`, `extension/`, `core/`); a domain's own `core/` (e.g. `submitqueue/core/`) holds infra shared only between that domain's services. A **single-service domain** collapses that split — the domain *is* the service, so its controllers live directly under the domain root (e.g. `runway/controller/`, `stovepipe/controller/`) with no `gateway/`/`orchestrator/` segment, and its wire contract is service-segment-free (`api/{domain}/`). `runway` is a consumer-only landing service with no gateway; `stovepipe` is currently a single Ping-only service that can grow the other layers (`entity/`, `extension/`, `core/`) as it gains real behavior.
67
71
68
-
The `api/` tree holds **published** wire contracts — those depended on from outside the owning domain. RPC contracts live at `api/{domain}/{service}/` (`proto/` for `.proto` sources, `protopb/` for committed generated Go); a service package may hold multiple `.proto` files, all generating into the same `protopb/`. External message-queue contracts live at `api/{domain}/messagequeue/` (see Message Queue Contracts below). Internal queue contracts do **not** go here — they live under `{domain}/core/messagequeue/`.
72
+
The `api/` tree holds **published** wire contracts — those depended on from outside the owning domain. RPC contracts live at `api/{domain}/{service}/` (`proto/` for `.proto` sources, `protopb/` for committed generated Go); for a single-service domain the service segment is dropped, so the contract lives directly at `api/{domain}/` (e.g. `api/runway/{proto,protopb}/`). A service package may hold multiple `.proto` files, all generating into the same `protopb/`. External message-queue contracts live at `api/{domain}/messagequeue/` (see Message Queue Contracts below). Internal queue contracts do **not** go here — they live under `{domain}/core/messagequeue/`.
69
73
70
74
### Platform notes
71
75
@@ -86,7 +90,7 @@ Each service follows the same layout:
86
90
└── {step}_test.go
87
91
```
88
92
89
-
Wire contracts for a service live separately under `api/{domain}/{service}/` (see Project Layout): `proto/` holds `.proto` sources and `protopb/` holds the committed generated stubs.
93
+
Wire contracts for a service live separately under `api/{domain}/{service}/` (see Project Layout): `proto/` holds `.proto` sources and `protopb/` holds the committed generated stubs. For a single-service domain the service root *is* the domain root (e.g. `runway/controller/`), and its wire contract lives at `api/{domain}/` (e.g. `api/runway/`) with no service segment.
90
94
91
95
### Controllers
92
96
@@ -152,9 +156,9 @@ When in doubt, ask: *"If the next implementation were DynamoDB / Kafka / Bigtabl
152
156
153
157
Paths follow the directory layout: shared packages live under `platform/` at the repo root; domain code nests under `submitqueue/`, `stovepipe/`, and other domain folders.
- Proto (generated): `github.com/uber/submitqueue/api/{domain}/{service}/protopb`
159
+
- RPC Controllers: `github.com/uber/submitqueue/{domain}/{service}/controller` (e.g. `.../submitqueue/gateway/controller`; single-service domains drop the `{service}` segment, e.g. `.../runway/controller`)
160
+
- Queue Controllers: `github.com/uber/submitqueue/{domain}/{service}/controller/{step}` (single-service: `.../runway/controller/{step}`, e.g. `.../runway/controller/merge`)
161
+
- Proto (generated): `github.com/uber/submitqueue/api/{domain}/{service}/protopb` (single-service: `.../api/{domain}/protopb`, e.g. `.../api/runway/protopb`)
@@ -60,16 +60,16 @@ build: ## Build all services and examples
60
60
@echo "Build complete!"
61
61
62
62
# Build Linux binaries required for Docker containers
63
-
build-all-linux: build-submitqueue-gateway-linux build-submitqueue-orchestrator-linux build-stovepipe-linux build-runway-orchestrator-linux ## Build all Linux binaries for Docker
63
+
build-all-linux: build-submitqueue-gateway-linux build-submitqueue-orchestrator-linux build-stovepipe-linux build-runway-linux ## Build all Linux binaries for Docker
64
64
@echo "All Linux binaries ready for Docker"
65
65
66
-
build-runway-orchestrator-linux: ## Build Runway orchestrator Linux binary for Docker
67
-
@echo "Building Runway orchestrator Linux binary for Docker..."
0 commit comments