2023-01-05 15:32:30 +00:00
|
|
|
// Copyright (C) 2022 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package rangedlooptest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-02-09 13:36:24 +00:00
|
|
|
"runtime"
|
2023-01-05 15:32:30 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"storj.io/storj/satellite/metabase/rangedloop"
|
|
|
|
)
|
|
|
|
|
|
|
|
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 {
|
2023-05-09 12:13:19 +01:00
|
|
|
OnProcess func(context.Context, []rangedloop.Segment) error
|
2023-01-05 15:32:30 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-02-09 13:36:24 +00:00
|
|
|
// delay ensures that using time.Now can be used to measure a visible duration.
|
|
|
|
func delay() {
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
// Windows time measurement is especially bad, so, we need to sleep more than
|
|
|
|
// for other environments.
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
} else {
|
|
|
|
time.Sleep(time.Microsecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-05 15:32:30 +00:00
|
|
|
// Start executes a callback at ranged segment loop start.
|
|
|
|
func (c *CallbackObserver) Start(ctx context.Context, time time.Time) error {
|
2023-02-09 13:36:24 +00:00
|
|
|
delay()
|
2023-01-05 15:32:30 +00:00
|
|
|
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) {
|
2023-02-09 13:36:24 +00:00
|
|
|
delay()
|
2023-01-05 15:32:30 +00:00
|
|
|
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 {
|
2023-02-09 13:36:24 +00:00
|
|
|
delay()
|
2023-01-05 15:32:30 +00:00
|
|
|
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 {
|
2023-02-09 13:36:24 +00:00
|
|
|
delay()
|
2023-01-05 15:32:30 +00:00
|
|
|
if c.OnFinish == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.OnFinish(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process executes a callback for every batch of segment in the ranged segment loop.
|
2023-05-09 12:13:19 +01:00
|
|
|
func (c *CallbackObserver) Process(ctx context.Context, segments []rangedloop.Segment) error {
|
2023-02-09 13:36:24 +00:00
|
|
|
delay()
|
2023-01-05 15:32:30 +00:00
|
|
|
if c.OnProcess == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return c.OnProcess(ctx, segments)
|
|
|
|
}
|