Skip to content

Commit 4bc4aef

Browse files
authored
feat(stovepipe): add orchestrator service (#182)
Set up stovepipe orchestrator service and ensure that the stack can be launched. ## Why? Similar to submitqueue, we will use the gateway service for API handling, and an orchestrator service to process work. This will give us more flexibility in deployment. ## What? Add separate orchestrator layer which will mainly be used to provide a controller that can be injected via fx and deployed. ## Test Plan - make local-stovepipe-start - CI
1 parent b4ad71e commit 4bc4aef

23 files changed

Lines changed: 1435 additions & 13 deletions

File tree

BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ load("@gazelle//:def.bzl", "gazelle")
66
# gazelle:resolve go github.com/uber/submitqueue/gateway/protopb //gateway/protopb
77
# gazelle:resolve go github.com/uber/submitqueue/orchestrator/protopb //orchestrator/protopb
88
# gazelle:resolve go github.com/uber/submitqueue/stovepipe/gateway/protopb //stovepipe/gateway/protopb
9+
# gazelle:resolve go github.com/uber/submitqueue/stovepipe/orchestrator/protopb //stovepipe/orchestrator/protopb
910

1011
# Export marker files for test data dependencies (used by FindRepoRoot in tests)
1112
exports_files(

Makefile

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ SUBMITQUEUE_LOCAL_PROJECT = submitqueue
1414

1515
# Stovepipe compose files
1616
STOVEPIPE_GATEWAY_COMPOSE_FILE = example/stovepipe/gateway/server/docker-compose.yml
17+
STOVEPIPE_ORCHESTRATOR_COMPOSE_FILE = example/stovepipe/orchestrator/server/docker-compose.yml
18+
STOVEPIPE_STACK_COMPOSE_FILE = example/stovepipe/docker-compose.yml
1719

1820
# Fixed project name for local manual testing (tests use unique random names)
1921
STOVEPIPE_LOCAL_PROJECT = stovepipe
@@ -38,7 +40,7 @@ define assert_clean
3840
fi
3941
endef
4042

41-
.PHONY: build build-all-linux build-gateway-linux build-orchestrator-linux build-stovepipe-gateway-linux check-gazelle check-mocks check-tidy clean clean-proto deps e2e-test fmt gazelle integration-test integration-test-consumer integration-test-extensions integration-test-gateway integration-test-orchestrator license-fix lint lint-fmt lint-license local-clean local-gateway-start local-gateway-stop local-init-schemas local-init-stovepipe-queue-schema local-logs local-orchestrator-start local-orchestrator-stop local-ps local-restart local-start local-stop local-stovepipe-gateway-start mocks proto query-deps query-targets run-client-gateway run-client-orchestrator run-client-stovepipe-gateway run-queue-admin test test-no-cache tidy tidy-bazel tidy-go help
43+
.PHONY: build build-all-linux build-gateway-linux build-orchestrator-linux build-stovepipe-gateway-linux build-stovepipe-orchestrator-linux check-gazelle check-mocks check-tidy clean clean-proto deps e2e-test fmt gazelle integration-test integration-test-consumer integration-test-extensions integration-test-gateway integration-test-orchestrator license-fix lint lint-fmt lint-license local-clean local-gateway-start local-gateway-stop local-init-schemas local-init-stovepipe-queue-schema local-logs local-orchestrator-start local-orchestrator-stop local-ps local-restart local-start local-stop local-stovepipe-gateway-start local-stovepipe-orchestrator-start local-stovepipe-start mocks proto query-deps query-targets run-client-gateway run-client-orchestrator run-client-stovepipe-gateway run-client-stovepipe-orchestrator run-queue-admin test test-no-cache tidy tidy-bazel tidy-go help
4244

4345

4446
build: ## Build all services and examples
@@ -47,7 +49,7 @@ build: ## Build all services and examples
4749
@echo "Build complete!"
4850

4951
# Build Linux binaries required for Docker containers
50-
build-all-linux: build-gateway-linux build-orchestrator-linux build-stovepipe-gateway-linux ## Build all Linux binaries for Docker
52+
build-all-linux: build-gateway-linux build-orchestrator-linux build-stovepipe-gateway-linux build-stovepipe-orchestrator-linux ## Build all Linux binaries for Docker
5153
@echo "All Linux binaries ready for Docker"
5254

5355
build-gateway-linux: ## Build Gateway Linux binary for Docker
@@ -74,6 +76,14 @@ build-stovepipe-gateway-linux: ## Build Stovepipe gateway Linux binary for Docke
7476
cp -f bazel-bin/example/stovepipe/gateway/server/gateway .docker-bin/stovepipe-gateway
7577
@echo "Stovepipe gateway Linux binary ready at .docker-bin/stovepipe-gateway"
7678

79+
build-stovepipe-orchestrator-linux: ## Build Stovepipe orchestrator Linux binary for Docker
80+
@echo "Building Stovepipe orchestrator Linux binary for Docker..."
81+
@$(BAZEL) build --platforms=@rules_go//go/toolchain:linux_amd64 //example/stovepipe/orchestrator/server:orchestrator
82+
@mkdir -p .docker-bin
83+
@cp -f bazel-bin/example/stovepipe/orchestrator/server/orchestrator_/orchestrator .docker-bin/stovepipe-orchestrator 2>/dev/null || \
84+
cp -f bazel-bin/example/stovepipe/orchestrator/server/orchestrator .docker-bin/stovepipe-orchestrator
85+
@echo "Stovepipe orchestrator Linux binary ready at .docker-bin/stovepipe-orchestrator"
86+
7787
check-gazelle: ## Check BUILD.bazel files are up to date
7888
@echo "Running Gazelle to check BUILD files..."
7989
@$(BAZEL) run //:gazelle
@@ -99,6 +109,7 @@ clean-proto: ## Clean generated proto files
99109
@rm -rf gateway/protopb/*.pb.go
100110
@rm -rf orchestrator/protopb/*.pb.go
101111
@rm -rf stovepipe/gateway/protopb/*.pb.go
112+
@rm -rf stovepipe/orchestrator/protopb/*.pb.go
102113
@echo "Proto clean complete!"
103114

104115
deps: tidy-go ## Download and tidy Go dependencies
@@ -266,9 +277,47 @@ local-start: build-all-linux ## Start full stack (Gateway + Orchestrator + MySQL
266277
local-stop: ## Stop all services (keep data)
267278
@echo "Stopping all services..."
268279
@$(COMPOSE) -f $(COMPOSE_FILE) -p $(SUBMITQUEUE_LOCAL_PROJECT) down
269-
@$(COMPOSE) -f $(STOVEPIPE_GATEWAY_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) down
280+
@$(COMPOSE) -f $(STOVEPIPE_STACK_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) down
270281
@echo "Services stopped. Data volumes preserved."
271282

283+
local-stovepipe-logs: ## View logs from all running Stovepipe services
284+
@$(COMPOSE) -f $(STOVEPIPE_STACK_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) logs -f
285+
286+
local-stovepipe-start: build-stovepipe-gateway-linux build-stovepipe-orchestrator-linux ## Start full Stovepipe stack (gateway + orchestrator + MySQL)
287+
@echo "Starting full Stovepipe stack with compose..."
288+
@$(COMPOSE) -f $(STOVEPIPE_STACK_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) up -d --build --wait
289+
@echo "Applying queue schema to mysql-queue (no Stovepipe app schema yet)..."
290+
@$(MAKE) -s local-init-stovepipe-queue-schema
291+
@echo ""
292+
@echo "✅ Full Stovepipe stack is running!"
293+
@echo ""
294+
@echo "Expected container NAMEs (project=$(STOVEPIPE_LOCAL_PROJECT), one replica each):"
295+
@echo " $(STOVEPIPE_LOCAL_PROJECT)-mysql-app-1"
296+
@echo " $(STOVEPIPE_LOCAL_PROJECT)-mysql-queue-1"
297+
@echo " $(STOVEPIPE_LOCAL_PROJECT)-gateway-service-1"
298+
@echo " $(STOVEPIPE_LOCAL_PROJECT)-orchestrator-service-1"
299+
@echo ""
300+
@$(COMPOSE) -f $(STOVEPIPE_STACK_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) ps
301+
@echo ""
302+
@echo "Stovepipe gateway gRPC port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-gateway-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
303+
@echo "Stovepipe orchestrator gRPC port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-orchestrator-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
304+
@echo "MySQL App port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-mysql-app-1 3306 2>/dev/null | cut -d: -f2 || echo 'unknown')"
305+
@echo "MySQL Queue port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-mysql-queue-1 3306 2>/dev/null | cut -d: -f2 || echo 'unknown')"
306+
307+
local-stovepipe-orchestrator-start: build-stovepipe-orchestrator-linux ## Start Stovepipe orchestrator locally (orchestrator + 2 MySQL databases)
308+
@echo "Starting Stovepipe orchestrator with compose..."
309+
@$(COMPOSE) -f $(STOVEPIPE_ORCHESTRATOR_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) up -d --build --wait
310+
@echo "Applying queue schema to mysql-queue (no Stovepipe app schema yet)..."
311+
@$(MAKE) -s local-init-stovepipe-queue-schema
312+
@echo ""
313+
@echo "✅ Stovepipe orchestrator is running!"
314+
@echo ""
315+
@$(COMPOSE) -f $(STOVEPIPE_ORCHESTRATOR_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) ps
316+
@echo ""
317+
@echo "Stovepipe orchestrator gRPC port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-orchestrator-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
318+
@echo "MySQL App port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-mysql-app-1 3306 2>/dev/null | cut -d: -f2 || echo 'unknown')"
319+
@echo "MySQL Queue port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-mysql-queue-1 3306 2>/dev/null | cut -d: -f2 || echo 'unknown')"
320+
272321
local-stovepipe-gateway-start: build-stovepipe-gateway-linux ## Start Stovepipe gateway locally (gateway + 2 MySQL databases)
273322
@echo "Starting Stovepipe gateway with compose..."
274323
@$(COMPOSE) -f $(STOVEPIPE_GATEWAY_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) up -d --build --wait
@@ -279,7 +328,7 @@ local-stovepipe-gateway-start: build-stovepipe-gateway-linux ## Start Stovepipe
279328
@echo ""
280329
@$(COMPOSE) -f $(STOVEPIPE_GATEWAY_COMPOSE_FILE) -p $(STOVEPIPE_LOCAL_PROJECT) ps
281330
@echo ""
282-
@echo "Stovepipe gateway gRPC port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-stovepipe-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
331+
@echo "Stovepipe gateway gRPC port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-gateway-service-1 8080 2>/dev/null | cut -d: -f2 || echo 'unknown')"
283332
@echo "MySQL App port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-mysql-app-1 3306 2>/dev/null | cut -d: -f2 || echo 'unknown')"
284333
@echo "MySQL Queue port: $$(docker port $(STOVEPIPE_LOCAL_PROJECT)-mysql-queue-1 3306 2>/dev/null | cut -d: -f2 || echo 'unknown')"
285334

@@ -302,6 +351,10 @@ proto: ## Generate protobuf files from .proto definitions
302351
--go-grpc_out=stovepipe/gateway/protopb --go-grpc_opt=paths=source_relative \
303352
--yarpc-go_out=stovepipe/gateway/protopb --yarpc-go_opt=paths=source_relative \
304353
--proto_path=stovepipe/gateway/proto stovepipe/gateway/proto/gateway.proto
354+
@protoc --go_out=stovepipe/orchestrator/protopb --go_opt=paths=source_relative \
355+
--go-grpc_out=stovepipe/orchestrator/protopb --go-grpc_opt=paths=source_relative \
356+
--yarpc-go_out=stovepipe/orchestrator/protopb --yarpc-go_opt=paths=source_relative \
357+
--proto_path=stovepipe/orchestrator/proto stovepipe/orchestrator/proto/orchestrator.proto
305358
@echo "Protobuf files generated successfully!"
306359

307360
# Bazel query helpers
@@ -323,6 +376,10 @@ run-client-orchestrator:
323376
run-client-stovepipe-gateway:
324377
@$(BAZEL) run //example/stovepipe/gateway/client:gateway -- -addr $(or $(SERVER_ADDR),localhost:8083) -message "$(or $(MESSAGE),ping)"
325378

379+
# Run stovepipe orchestrator client (connects to any running stovepipe orchestrator service)
380+
run-client-stovepipe-orchestrator:
381+
@$(BAZEL) run //example/stovepipe/orchestrator/client:orchestrator -- -addr $(or $(SERVER_ADDR),localhost:8084) -message "$(or $(MESSAGE),ping)"
382+
326383
run-queue-admin: ## Run queue-admin CLI (use ARGS to pass arguments, e.g. make run-queue-admin ARGS="list-topics")
327384
@$(BAZEL) run //extension/queue/mysql/ctl -- $(ARGS)
328385

example/README.md

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Example gRPC servers and clients for running the submitqueue services locally.
77
- **SubmitQueue Gateway** (port 8081) — entry point for land requests. Exposes `Ping` and `Land` RPCs.
88
- **SubmitQueue Orchestrator** (port 8082) — coordinates the pipeline. Exposes `Ping` RPC and consumes queue messages across 9 pipeline topics.
99
- **Stovepipe Gateway** (port 8083) - entry point for commit deployment verification requests. Exposes `Ping` RPC.
10+
- **Stovepipe Orchestrator** (port 8084) - coordinates the commit verification pipeline. Exposes `Ping` RPC.
1011

1112
Services require MySQL (app database + queue database). Docker Compose handles this automatically.
1213

@@ -28,12 +29,19 @@ example/
2829
│ ├── gateway/main.go # Gateway ping client
2930
│ └── orchestrator/main.go # Orchestrator ping client
3031
└── stovepipe/
31-
└── gateway/
32+
├── docker-compose.yml # Full stack (Stovepipe Gateway + Orchestrator + 2x MySQL)
33+
├── gateway/
34+
│ ├── server/
35+
│ │ ├── main.go # Stovepipe gateway gRPC server (Docker: :8080; go run default :8083)
36+
│ │ ├── Dockerfile
37+
│ │ └── docker-compose.yml # Gateway-only stack
38+
│ └── client/main.go # Stovepipe gateway ping client
39+
└── orchestrator/
3240
├── server/
33-
│ ├── main.go # Stovepipe gateway gRPC server (Docker: :8080; go run default :8083)
41+
│ ├── main.go # Stovepipe orchestrator gRPC server (Docker: :8080; go run default :8084)
3442
│ ├── Dockerfile
35-
│ └── docker-compose.yml # Gateway-only stack
36-
└── client/main.go # Stovepipe gateway ping client
43+
│ └── docker-compose.yml # Orchestrator-only stack
44+
└── client/main.go # Stovepipe orchestrator ping client
3745
```
3846

3947
## Running
@@ -47,8 +55,10 @@ make local-start
4755
make local-gateway-start
4856
make local-orchestrator-start
4957

50-
# Start Stovepipe gateway (Gateway + 2x MySQL)
58+
# Start full Stovepipe stack (Gateway + Orchestrator + MySQL)
59+
make local-stovepipe-start
5160
make local-stovepipe-gateway-start
61+
make local-stovepipe-orchestrator-start
5262

5363
# View logs and status
5464
make local-logs
@@ -58,7 +68,7 @@ make local-ps
5868
make local-stop
5969
```
6070

61-
For Docker, `make build-stovepipe-gateway-linux` copies a Linux binary to `.docker-bin/stovepipe-gateway` so it does not overwrite SubmitQueue’s `.docker-bin/gateway`. Stovepipe `make local-stovepipe-gateway-start` applies **only the queue schema** on `mysql-queue` (`make local-init-stovepipe-queue-schema`); SubmitQueue storage/counter schemas on `mysql-app` are skipped until Stovepipe has its own app schema. `make local-stop` stops the SubmitQueue stack and runs `docker compose down` on the Stovepipe gateway compose file for **`STOVEPIPE_LOCAL_PROJECT`** (default `stovepipe`). SubmitQueue examples use project **`submitqueue`** by default (`make SUBMITQUEUE_LOCAL_PROJECT=myname ...`). Stovepipe containers are named like `stovepipe-mysql-app-1`, not `submitqueue-*`.
71+
For Docker, `make build-stovepipe-gateway-linux` copies a Linux binary to `.docker-bin/stovepipe-gateway` so it does not overwrite SubmitQueue’s `.docker-bin/gateway`. Stovepipe `make local-stovepipe-gateway-start` applies **only the queue schema** on `mysql-queue` (`make local-init-stovepipe-queue-schema`); SubmitQueue storage/counter schemas on `mysql-app` are skipped until Stovepipe has its own app schema. Compose service keys are **`gateway-service`** and **`orchestrator-service`** (same as `example/server`), so with default project **`stovepipe`** you should see **`stovepipe-gateway-service-1`** and **`stovepipe-orchestrator-service-1`** — not `stovepipe-stovepipe-*` (that pattern was from older service names; run **`make local-stop`** to run `docker compose down --remove-orphans` and drop orphans). `make local-stop` also stops the SubmitQueue stack. SubmitQueue examples use project **`submitqueue`** by default (`make SUBMITQUEUE_LOCAL_PROJECT=myname ...`). Stovepipe containers are named like `stovepipe-mysql-app-1`, not `submitqueue-*`.
6272

6373
### Bazel
6474

@@ -67,11 +77,13 @@ For Docker, `make build-stovepipe-gateway-linux` copies a Linux binary to `.dock
6777
bazel build //example/server/gateway:gateway
6878
bazel build //example/server/orchestrator:orchestrator
6979
bazel build //example/stovepipe/gateway/server:gateway
80+
bazel build //example/stovepipe/orchestrator/server:orchestrator
7081

7182
# Build clients
7283
bazel build //example/client/gateway:gateway
7384
bazel build //example/client/orchestrator:orchestrator
7485
bazel build //example/stovepipe/gateway/client:gateway
86+
bazel build //example/stovepipe/orchestrator/client:orchestrator
7587
```
7688

7789
### Go
@@ -80,6 +92,7 @@ bazel build //example/stovepipe/gateway/client:gateway
8092
go run example/server/gateway/main.go
8193
go run example/server/orchestrator/main.go
8294
go run example/stovepipe/gateway/server/main.go
95+
go run example/stovepipe/orchestrator/server/main.go
8396
```
8497

8598
## Testing with Clients
@@ -89,6 +102,7 @@ go run example/stovepipe/gateway/server/main.go
89102
go run example/client/gateway/main.go -addr localhost:8081 -message "hello"
90103
go run example/client/orchestrator/main.go -addr localhost:8082 -message "hello"
91104
go run example/stovepipe/gateway/client/main.go -addr localhost:8083 -message "hello"
105+
go run example/stovepipe/orchestrator/client/main.go -addr localhost:8084 -message "hello"
92106
```
93107

94108
Client flags:
@@ -110,16 +124,19 @@ go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
110124
grpcurl -plaintext -d '{"message": "hello"}' localhost:8081 uber.submitqueue.gateway.SubmitQueueGateway/Ping
111125
grpcurl -plaintext -d '{"message": "hello"}' localhost:8082 uber.submitqueue.orchestrator.SubmitQueueOrchestrator/Ping
112126
grpcurl -plaintext -d '{"message": "hello"}' localhost:8083 uber.submitqueue.stovepipe.StovepipeGateway/Ping
127+
grpcurl -plaintext -d '{"message": "hello"}' localhost:8084 uber.submitqueue.stovepipe.orchestrator.StovepipeOrchestrator/Ping
113128

114129
# List services
115130
grpcurl -plaintext localhost:8081 list
116131
grpcurl -plaintext localhost:8082 list
117132
grpcurl -plaintext localhost:8083 list
133+
grpcurl -plaintext localhost:8084 list
118134

119135
# Describe a service
120136
grpcurl -plaintext localhost:8081 describe uber.submitqueue.gateway.SubmitQueueGateway
121137
grpcurl -plaintext localhost:8082 describe uber.submitqueue.orchestrator.SubmitQueueOrchestrator
122138
grpcurl -plaintext localhost:8083 describe uber.submitqueue.stovepipe.StovepipeGateway
139+
grpcurl -plaintext localhost:8084 describe uber.submitqueue.stovepipe.orchestrator.StovepipeOrchestrator
123140
```
124141

125142
## API Reference
@@ -151,3 +168,12 @@ grpcurl -plaintext localhost:8083 describe uber.submitqueue.stovepipe.StovepipeG
151168
| Method | Description |
152169
|--------|-------------|
153170
| `Ping` | Health check |
171+
172+
### Stovepipe Orchestrator
173+
174+
**Service**: `uber.submitqueue.stovepipe.orchestrator.StovepipeOrchestrator`
175+
**Proto**: `stovepipe/orchestrator/proto/orchestrator.proto`
176+
177+
| Method | Description |
178+
|--------|-------------|
179+
| `Ping` | Health check |

example/stovepipe/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
exports_files(
2+
["docker-compose.yml"],
3+
visibility = ["//visibility:public"],
4+
)

0 commit comments

Comments
 (0)