Skip to content

Commit 585d2b4

Browse files
committed
feat(stovepipe): wire build controller into server
1 parent 83caa80 commit 585d2b4

2 files changed

Lines changed: 95 additions & 21 deletions

File tree

service/stovepipe/server/BUILD.bazel

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@ go_library(
1515
"//platform/extension/messagequeue/mysql:go_default_library",
1616
"//service/stovepipe/server/mapper:go_default_library",
1717
"//stovepipe/controller:go_default_library",
18+
"//stovepipe/controller/build:go_default_library",
1819
"//stovepipe/controller/dlq:go_default_library",
1920
"//stovepipe/controller/process:go_default_library",
2021
"//stovepipe/core/messagequeue:go_default_library",
22+
"//stovepipe/extension/buildrunner:go_default_library",
23+
"//stovepipe/extension/buildrunner/fake:go_default_library",
2124
"//stovepipe/extension/queueconfig/default:go_default_library",
2225
"//stovepipe/extension/sourcecontrol:go_default_library",
2326
"//stovepipe/extension/sourcecontrol/fake:go_default_library",
27+
"//stovepipe/extension/storage:go_default_library",
2428
"//stovepipe/extension/storage/mysql:go_default_library",
2529
"@com_github_go_sql_driver_mysql//:go_default_library",
2630
"@com_github_uber_go_tally//:go_default_library",
@@ -31,7 +35,7 @@ go_library(
3135
)
3236

3337
go_binary(
34-
name = "stovepipe",
38+
name = "server",
3539
embed = [":go_default_library"],
3640
visibility = ["//visibility:public"],
3741
)

service/stovepipe/server/main.go

Lines changed: 90 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,16 @@ import (
3737
queueMySQL "github.com/uber/submitqueue/platform/extension/messagequeue/mysql"
3838
"github.com/uber/submitqueue/service/stovepipe/server/mapper"
3939
"github.com/uber/submitqueue/stovepipe/controller"
40+
"github.com/uber/submitqueue/stovepipe/controller/build"
4041
"github.com/uber/submitqueue/stovepipe/controller/dlq"
4142
"github.com/uber/submitqueue/stovepipe/controller/process"
4243
stovepipemq "github.com/uber/submitqueue/stovepipe/core/messagequeue"
44+
"github.com/uber/submitqueue/stovepipe/extension/buildrunner"
45+
buildrunnerfake "github.com/uber/submitqueue/stovepipe/extension/buildrunner/fake"
4346
queueconfigdefault "github.com/uber/submitqueue/stovepipe/extension/queueconfig/default"
4447
"github.com/uber/submitqueue/stovepipe/extension/sourcecontrol"
4548
sourcecontrolfake "github.com/uber/submitqueue/stovepipe/extension/sourcecontrol/fake"
49+
"github.com/uber/submitqueue/stovepipe/extension/storage"
4650
storageMySQL "github.com/uber/submitqueue/stovepipe/extension/storage/mysql"
4751
"go.uber.org/zap"
4852
"google.golang.org/grpc"
@@ -100,6 +104,15 @@ func (fakeSourceControlFactory) For(cfg sourcecontrol.Config) (sourcecontrol.Sou
100104
return sourcecontrolfake.New([]string{fmt.Sprintf("git://%s/HEAD", cfg.QueueName)}), nil
101105
}
102106

107+
// fakeBuildRunnerFactory is the example BuildRunner factory: every queue shares the same
108+
// stateless fake runner, which succeeds unless a caller embeds a failure marker in the head
109+
// URI. A real deployment supplies a backend-specific factory (e.g. Buildkite, per queue).
110+
type fakeBuildRunnerFactory struct{}
111+
112+
func (fakeBuildRunnerFactory) For(_ buildrunner.Config) (buildrunner.BuildRunner, error) {
113+
return buildrunnerfake.New(), nil
114+
}
115+
103116
func main() {
104117
code := 0
105118
if err := run(); err != nil {
@@ -225,24 +238,21 @@ func run() error {
225238
errs.AlwaysRetryableProcessor,
226239
)
227240

228-
processController := process.NewController(
229-
logger.Sugar(),
230-
scope,
231-
store,
232-
queueconfigdefault.NewStore(),
233-
fakeSourceControlFactory{},
234-
registry,
235-
stovepipemq.TopicKeyProcess,
236-
"stovepipe-process",
237-
)
238-
if err := primaryConsumer.Register(processController); err != nil {
239-
return fmt.Errorf("failed to register process controller: %w", err)
240-
}
241+
// Each factory is constructed once and threaded through every consumer of
242+
// it, so a real (stateful) backend introduced later is shared rather than
243+
// silently duplicated across controllers.
244+
scf := fakeSourceControlFactory{}
245+
brf := fakeBuildRunnerFactory{}
241246

242-
processDLQController := dlq.NewController(logger.Sugar(), scope, store, dlq.TopicKey(stovepipemq.TopicKeyProcess), "stovepipe-process-dlq")
243-
if err := dlqConsumer.Register(processDLQController); err != nil {
244-
return fmt.Errorf("failed to register process dlq controller: %w", err)
247+
primaryCount, err := registerPrimaryControllers(primaryConsumer, logger.Sugar(), scope, store, registry, scf, brf)
248+
if err != nil {
249+
return err
245250
}
251+
dlqCount, err := registerDLQControllers(dlqConsumer, logger.Sugar(), scope, store, registry)
252+
if err != nil {
253+
return err
254+
}
255+
logger.Info("controllers registered", zap.Int("primary", primaryCount), zap.Int("dlq", dlqCount))
246256

247257
// Start consumers. DLQ first because Start begins processing messages
248258
// immediately; if the primary consumer then fails to start, the half we
@@ -266,7 +276,7 @@ func run() error {
266276
logger.Sugar(),
267277
scope,
268278
newInMemoryCounter(),
269-
fakeSourceControlFactory{},
279+
scf,
270280
store,
271281
registry,
272282
)
@@ -338,10 +348,67 @@ func run() error {
338348
return err
339349
}
340350

351+
// registerPrimaryControllers creates the primary-pipeline queue controllers and
352+
// registers them with c, returning how many were registered.
353+
func registerPrimaryControllers(
354+
c consumer.Consumer,
355+
logger *zap.SugaredLogger,
356+
scope tally.Scope,
357+
store storage.Storage,
358+
registry consumer.TopicRegistry,
359+
scf sourcecontrol.Factory,
360+
brf buildrunner.Factory,
361+
) (int, error) {
362+
var count int
363+
364+
processController := process.NewController(
365+
logger,
366+
scope,
367+
store,
368+
queueconfigdefault.NewStore(),
369+
scf,
370+
registry,
371+
stovepipemq.TopicKeyProcess,
372+
"stovepipe-process",
373+
)
374+
if err := c.Register(processController); err != nil {
375+
return count, fmt.Errorf("failed to register process controller: %w", err)
376+
}
377+
count++
378+
379+
buildController := build.NewController(logger, scope, store, brf, registry, stovepipemq.TopicKeyBuild, "stovepipe-build")
380+
if err := c.Register(buildController); err != nil {
381+
return count, fmt.Errorf("failed to register build controller: %w", err)
382+
}
383+
count++
384+
385+
return count, nil
386+
}
387+
388+
// registerDLQControllers creates one DLQ reconciler per primary stage and
389+
// registers them with c, returning how many were registered.
390+
func registerDLQControllers(
391+
c consumer.Consumer,
392+
logger *zap.SugaredLogger,
393+
scope tally.Scope,
394+
store storage.Storage,
395+
registry consumer.TopicRegistry,
396+
) (int, error) {
397+
var count int
398+
399+
processDLQController := dlq.NewController(logger, scope, store, dlq.TopicKey(stovepipemq.TopicKeyProcess), "stovepipe-process-dlq")
400+
if err := c.Register(processDLQController); err != nil {
401+
return count, fmt.Errorf("failed to register process dlq controller: %w", err)
402+
}
403+
count++
404+
405+
return count, nil
406+
}
407+
341408
// newTopicRegistry builds the TopicRegistry for Stovepipe's internal pipeline queues. ingest
342-
// publishes to process; process publishes admitted requests to the publish-only build topic.
343-
// The process_dlq topic is the dead-letter destination the queue backend routes to (per
344-
// DefaultSubscriptionConfig's DLQ.TopicSuffix) when the process controller exhausts retries.
409+
// publishes to the process topic and the process consumer subscribes to it; process publishes
410+
// to the build topic and the build consumer subscribes to it. The buildsignal topic is added
411+
// once the buildsignal controller lands to consume it.
345412
func newTopicRegistry(q extqueue.Queue, subscriberName string) (consumer.TopicRegistry, error) {
346413
return consumer.NewTopicRegistry([]consumer.TopicConfig{
347414
{
@@ -356,6 +423,9 @@ func newTopicRegistry(q extqueue.Queue, subscriberName string) (consumer.TopicRe
356423
Key: stovepipemq.TopicKeyBuild,
357424
Name: "build",
358425
Queue: q,
426+
Subscription: extqueue.DefaultSubscriptionConfig(
427+
subscriberName, "stovepipe-build",
428+
),
359429
},
360430
{
361431
Key: dlq.TopicKey(stovepipemq.TopicKeyProcess),

0 commit comments

Comments
 (0)