Skip to content

Commit 6607b6a

Browse files
Merge branch 'master' into split-resource-kind-storage-access
2 parents 84c9634 + ef87792 commit 6607b6a

5 files changed

Lines changed: 64 additions & 17 deletions

File tree

broadcastclients/broadcastclients.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ func (r *Router) AddBroadcastMessages(feedMessages []*message.BroadcastFeedMessa
4141
}
4242

4343
type BroadcastClients struct {
44+
stopwaiter.StopWaiter
4445
primaryClients []*broadcastclient.BroadcastClient
4546
secondaryClients []*broadcastclient.BroadcastClient
4647
secondaryURL []string
@@ -135,17 +136,18 @@ func clearAndResetTicker(timer *time.Ticker, interval time.Duration) {
135136
}
136137

137138
func (bcs *BroadcastClients) Start(ctx context.Context) {
138-
bcs.primaryRouter.StopWaiter.Start(ctx, bcs.primaryRouter)
139-
bcs.secondaryRouter.StopWaiter.Start(ctx, bcs.secondaryRouter)
139+
bcs.StopWaiter.Start(ctx, bcs)
140+
bcs.primaryRouter.StopWaiter.Start(bcs.GetContext(), bcs.primaryRouter)
141+
bcs.secondaryRouter.StopWaiter.Start(bcs.GetContext(), bcs.secondaryRouter)
140142

141143
for _, client := range bcs.primaryClients {
142-
client.Start(ctx)
144+
client.Start(bcs.GetContext())
143145
}
144146

145147
var lastConfirmed arbutil.MessageIndex
146148
recentFeedItemsNew := make(map[arbutil.MessageIndex]time.Time, RECENT_FEED_INITIAL_MAP_SIZE)
147149
recentFeedItemsOld := make(map[arbutil.MessageIndex]time.Time, RECENT_FEED_INITIAL_MAP_SIZE)
148-
bcs.primaryRouter.LaunchThread(func(ctx context.Context) {
150+
bcs.LaunchThread(func(ctx context.Context) {
149151
recentFeedItemsCleanup := time.NewTicker(RECENT_FEED_ITEM_TTL)
150152
startSecondaryFeedTimer := time.NewTicker(MAX_FEED_INACTIVE_TIME)
151153
stopSecondaryFeedTimer := time.NewTicker(PRIMARY_FEED_UPTIME)
@@ -297,10 +299,13 @@ func (bcs *BroadcastClients) stopSecondaryFeed() {
297299
}
298300

299301
func (bcs *BroadcastClients) StopAndWait() {
300-
for _, client := range bcs.primaryClients {
302+
for _, client := range bcs.secondaryClients {
301303
client.StopAndWait()
302304
}
303-
for _, client := range bcs.secondaryClients {
305+
for _, client := range bcs.primaryClients {
304306
client.StopAndWait()
305307
}
308+
bcs.secondaryRouter.StopWaiter.StopAndWait()
309+
bcs.primaryRouter.StopWaiter.StopAndWait()
310+
bcs.StopWaiter.StopAndWait()
306311
}

changelog/pmikolajczyk-nit-4667.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### Fixed
2+
- Fix ValidationSpawnerRetryWrapper lifecycle: reuse one wrapper per module root instead of creating and leaking one per validation
3+
- Fix BroadcastClients launching coordination goroutine on child Router's StopWaiter instead of its own
4+
- Fix ValidationServer and ExecutionSpawner missing StopAndWait for their children

staker/block_validator.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ func (t *WorkerThrottler) Release() {
7575
}
7676

7777
type ThrottledValidationSpawner struct {
78-
Spawner validator.ValidationSpawner
78+
Spawner *retry_wrapper.ValidationSpawnerRetryWrapper
7979
Throttler *WorkerThrottler
8080
}
8181

8282
func NewThrottledValidationSpawner(spawner validator.ValidationSpawner) *ThrottledValidationSpawner {
8383
return &ThrottledValidationSpawner{
84-
Spawner: spawner,
84+
Spawner: retry_wrapper.NewValidationSpawnerRetryWrapper(spawner),
8585
Throttler: &WorkerThrottler{maxWorkers: spawner.Capacity()},
8686
}
8787
}
@@ -996,9 +996,7 @@ func (v *BlockValidator) sendValidations(ctx context.Context) (*arbutil.MessageI
996996
var runs []validator.ValidationRun
997997
for _, moduleRoot := range wasmRoots {
998998
throttledSpawner := v.chosenValidator[moduleRoot]
999-
spawner := retry_wrapper.NewValidationSpawnerRetryWrapper(throttledSpawner.Spawner)
1000-
spawner.StopWaiter.Start(ctx, v)
1001-
input, err := validationStatus.Entry.ToInput(spawner.StylusArchs())
999+
input, err := validationStatus.Entry.ToInput(throttledSpawner.Spawner.StylusArchs())
10021000
if err != nil && ctx.Err() == nil {
10031001
v.possiblyFatal(fmt.Errorf("%w: error preparing validation", err))
10041002
throttledSpawner.Throttler.Release()
@@ -1011,7 +1009,7 @@ func (v *BlockValidator) sendValidations(ctx context.Context) (*arbutil.MessageI
10111009
}
10121010
return nil, ctx.Err()
10131011
}
1014-
run := spawner.LaunchWithNAllowedAttempts(input, moduleRoot, v.config().ValidationSpawningAllowedAttempts, v.config().ValidationSpawningAllowedTimeouts)
1012+
run := throttledSpawner.Spawner.LaunchWithNAllowedAttempts(input, moduleRoot, v.config().ValidationSpawningAllowedAttempts, v.config().ValidationSpawningAllowedTimeouts)
10151013
log.Trace("sendValidations: launched", "pos", validationStatus.Entry.Pos, "moduleRoot", moduleRoot)
10161014
runs = append(runs, run)
10171015
}
@@ -1558,12 +1556,18 @@ func (v *BlockValidator) LaunchWorkthreadsWhenCaughtUp(ctx context.Context) {
15581556

15591557
func (v *BlockValidator) Start(ctxIn context.Context) error {
15601558
v.StopWaiter.Start(ctxIn, v)
1559+
for _, throttled := range v.chosenValidator {
1560+
throttled.Spawner.Start(v.GetContext())
1561+
}
15611562
v.LaunchThread(v.LaunchWorkthreadsWhenCaughtUp)
15621563
v.CallIteratively(v.iterativeValidationPrint)
15631564
return nil
15641565
}
15651566

15661567
func (v *BlockValidator) StopAndWait() {
1568+
for _, throttled := range v.chosenValidator {
1569+
throttled.Spawner.StopAndWait()
1570+
}
15671571
v.StopWaiter.StopAndWait()
15681572
}
15691573

validator/retry_wrapper/retry_wrapper.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ func NewValidationSpawnerRetryWrapper(spawner validator.ValidationSpawner) *Vali
2525
}
2626
}
2727

28+
func (v *ValidationSpawnerRetryWrapper) Start(ctx context.Context) {
29+
v.StopWaiter.Start(ctx, v)
30+
}
31+
2832
// LaunchWithNAllowedAttempts launches the validation with a specified number of
2933
// allowed attempts to retry in case of failure. Timeout errors have their own
3034
// separate counter (allowedTimeouts) since they typically represent transient

validator/valnode/redis/consumer.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import (
2525
// RedisValidationClient producers.
2626
type ValidationServer struct {
2727
stopwaiter.StopWaiter
28-
spawner validator.ExecutionSpawner
28+
spawner validator.ExecutionSpawner
29+
boldSpawner *ExecutionSpawner
2930

3031
// consumers stores moduleRoot to consumer mapping.
3132
consumers map[common.Hash]*pubsub.Consumer[*validator.ValidationInput, validator.GoGlobalState]
@@ -59,7 +60,7 @@ func NewValidationServer(cfg *ValidationServerConfig, spawner validator.Executio
5960

6061
func (s *ValidationServer) Start(ctx_in context.Context) {
6162
s.StopWaiter.Start(ctx_in, s)
62-
s.StartBoldSpawner(s.GetContext())
63+
s.startBoldSpawner()
6364
// Channel that all consumers use to indicate their readiness.
6465
readyStreams := make(chan struct{}, len(s.consumers))
6566
type workUnit struct {
@@ -192,12 +193,34 @@ func (s *ValidationServer) Start(ctx_in context.Context) {
192193
}
193194
}
194195

195-
func (s *ValidationServer) StartBoldSpawner(ctx context.Context) {
196-
boldSpawner, err := NewExecutionSpawner(s.config, s.spawner)
196+
func (s *ValidationServer) StopOnly() {
197+
if s.boldSpawner != nil {
198+
s.boldSpawner.StopOnly()
199+
}
200+
for _, c := range s.consumers {
201+
c.StopOnly()
202+
}
203+
s.StopWaiter.StopOnly()
204+
}
205+
206+
func (s *ValidationServer) StopAndWait() {
207+
if s.boldSpawner != nil {
208+
s.boldSpawner.StopAndWait()
209+
}
210+
for _, c := range s.consumers {
211+
c.StopAndWait()
212+
}
213+
s.StopWaiter.StopAndWait()
214+
}
215+
216+
func (s *ValidationServer) startBoldSpawner() {
217+
var err error
218+
s.boldSpawner, err = NewExecutionSpawner(s.config, s.spawner)
197219
if err != nil {
198220
log.Error("creating redis execution spawner", "error", err)
221+
return
199222
}
200-
boldSpawner.Start(ctx)
223+
s.boldSpawner.Start(s.GetContext())
201224
}
202225

203226
type ExecutionSpawner struct {
@@ -233,6 +256,13 @@ func NewExecutionSpawner(cfg *ValidationServerConfig, spawner validator.Executio
233256
}, nil
234257
}
235258

259+
func (s *ExecutionSpawner) StopAndWait() {
260+
for _, c := range s.consumers {
261+
c.StopAndWait()
262+
}
263+
s.StopWaiter.StopAndWait()
264+
}
265+
236266
func (s *ExecutionSpawner) Start(ctx_in context.Context) {
237267
s.StopWaiter.Start(ctx_in, s)
238268
// Channel that all consumers use to indicate their readiness.

0 commit comments

Comments
 (0)