Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
satellite/metabase/rangedloop: cancellation (#5364)
Support interruption of the ranged segment loop through context. Part of #5223 Change-Id: Iae0260e250f8ea33affed95c6592a1f42df384eb
- Loading branch information
Showing
5 changed files
with
165 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
satellite/metabase/rangedloop/rangedlooptest/callbackobserver.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Copyright (C) 2022 Storj Labs, Inc. | ||
// See LICENSE for copying information. | ||
|
||
package rangedlooptest | ||
|
||
import ( | ||
"context" | ||
"time" | ||
|
||
"storj.io/storj/satellite/metabase/rangedloop" | ||
"storj.io/storj/satellite/metabase/segmentloop" | ||
) | ||
|
||
var _ rangedloop.Observer = (*CallbackObserver)(nil) | ||
var _ rangedloop.Partial = (*CallbackObserver)(nil) | ||
|
||
// CallbackObserver can be used to easily attach logic to the ranged segment loop during tests. | ||
type CallbackObserver struct { | ||
OnProcess func(context.Context, []segmentloop.Segment) error | ||
OnStart func(context.Context, time.Time) error | ||
OnFork func(context.Context) (rangedloop.Partial, error) | ||
OnJoin func(context.Context, rangedloop.Partial) error | ||
OnFinish func(context.Context) error | ||
} | ||
|
||
// Start executes a callback at ranged segment loop start. | ||
func (c *CallbackObserver) Start(ctx context.Context, time time.Time) error { | ||
if c.OnStart == nil { | ||
return nil | ||
} | ||
|
||
return c.OnStart(ctx, time) | ||
} | ||
|
||
// Fork executes a callback for every segment range at ranged segment loop fork stage. | ||
func (c *CallbackObserver) Fork(ctx context.Context) (rangedloop.Partial, error) { | ||
if c.OnFork == nil { | ||
return c, nil | ||
} | ||
|
||
partial, err := c.OnFork(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if partial == nil { | ||
return c, nil | ||
} | ||
|
||
return partial, nil | ||
} | ||
|
||
// Join executes a callback for every segment range at ranged segment loop join stage. | ||
func (c *CallbackObserver) Join(ctx context.Context, partial rangedloop.Partial) error { | ||
if c.OnJoin == nil { | ||
return nil | ||
} | ||
|
||
return c.OnJoin(ctx, partial) | ||
} | ||
|
||
// Finish executes a callback at ranged segment loop end. | ||
func (c *CallbackObserver) Finish(ctx context.Context) error { | ||
if c.OnFinish == nil { | ||
return nil | ||
} | ||
|
||
return c.OnFinish(ctx) | ||
} | ||
|
||
// Process executes a callback for every batch of segment in the ranged segment loop. | ||
func (c *CallbackObserver) Process(ctx context.Context, segments []segmentloop.Segment) error { | ||
if c.OnProcess == nil { | ||
return nil | ||
} | ||
|
||
return c.OnProcess(ctx, segments) | ||
} |
36 changes: 36 additions & 0 deletions
36
satellite/metabase/rangedloop/rangedlooptest/infiniteprovider.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (C) 2022 Storj Labs, Inc. | ||
// See LICENSE for copying information. | ||
|
||
package rangedlooptest | ||
|
||
import ( | ||
"context" | ||
|
||
"storj.io/storj/satellite/metabase/rangedloop" | ||
"storj.io/storj/satellite/metabase/segmentloop" | ||
) | ||
|
||
var _ rangedloop.RangeSplitter = (*InfiniteSegmentProvider)(nil) | ||
var _ rangedloop.SegmentProvider = (*InfiniteSegmentProvider)(nil) | ||
|
||
// InfiniteSegmentProvider allow to iterate indefinitely to test service cancellation. | ||
type InfiniteSegmentProvider struct { | ||
} | ||
|
||
// CreateRanges splits the segments into equal ranges. | ||
func (m *InfiniteSegmentProvider) CreateRanges(nRanges int, batchSize int) (segmentsProviders []rangedloop.SegmentProvider, err error) { | ||
for i := 0; i < nRanges; i++ { | ||
segmentsProviders = append(segmentsProviders, &InfiniteSegmentProvider{}) | ||
} | ||
return segmentsProviders, nil | ||
} | ||
|
||
// Iterate allows to loop over the segments stored in the provider. | ||
func (m *InfiniteSegmentProvider) Iterate(ctx context.Context, fn func([]segmentloop.Segment) error) error { | ||
for { | ||
err := fn(make([]segmentloop.Segment, 3)) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters