loadtester

package
v3.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 29, 2023 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBadReadTasksImpl     = errors.New("bad ReadTasks implementation: returned a value less than zero or larger than the input slice length")
	ErrRetriesFailedToFlush = errors.New("failed to flush all retries")
)

Functions

func NewLogger

func NewLogger(level slog.Level) (*slog.Logger, error)

NewLogger should likely be followed by a call to slog.SetDefault with the logger returned by this function if called in the program's main context.

func NewOpts

func NewOpts() newOpts

func RootContext

func RootContext(logger StructuredLogger) (context.Context, func())

RootContext returns a context that is canceled when the system process receives an interrupt, sigint, or sigterm

Also returns a function that can be used to cancel the context.

Types

type ConfigUpdate

type ConfigUpdate struct {
	// contains filtered or unexported fields
}

func (*ConfigUpdate) SetInterval

func (cu *ConfigUpdate) SetInterval(d time.Duration)

func (*ConfigUpdate) SetNumIntervalTasks

func (cu *ConfigUpdate) SetNumIntervalTasks(n int)

func (*ConfigUpdate) SetNumWorkers

func (cu *ConfigUpdate) SetNumWorkers(n int)

type DoRetryChecker

type DoRetryChecker interface {
	DoRetryer
	RetryChecker
}

type DoRetryer

type DoRetryer interface {
	Doer
	Retryer
}

DoRetryer interface is useful for tasks that have no retry count upper bound

If you need to have a retry upper bound, then have your task implement DoRetryChecker

type Doer

type Doer interface {
	Do(ctx context.Context, workerID int) error
}

Doer is a basic task unit

If your Doer also implements Retryer then note that Doer can be run again in a different thread if your worker size is greater than one.

If you want your task to have a retry upper bound then implement DoRetryChecker

type Loadtest

type Loadtest struct {
	// contains filtered or unexported fields
}

func NewLoadtest

func NewLoadtest(options ...LoadtestOption) (*Loadtest, error)

func (*Loadtest) NewHttpTransport

func (lt *Loadtest) NewHttpTransport() *http.Transport

HttpTransport returns a new configured *http.Transport which implements http.RoundTripper that can be used in tasks which have http clients

Note, you may need to increase the value of MaxIdleConns if your tasks target multiple hosts. MaxIdleConnsPerHost does not override the limit established by MaxIdleConns and if the tasks are expected to communicate to multiple hosts you probably need to apply some scaling factor to it to let connections go idle for a time and still be reusable.

Note that if you are not connecting to a load balancer which preserves connections to a client much of the intent we're trying to establish here is not applicable.

Also if the load balancer does not have "max connection lifespan" behavior nor a "round robin" or "connection balancing" feature without forcing the loadtesting client to reconnect then as you increase load your established connections may prevent the spread of load to newly scaled-out recipients of that load.

By default golang's http standard lib does not expose a way for us to attempt to address this. The problem is also worse if your load balancer ( or number of exposed ips for a dns record ) increase.

Rectifying this issue requires a fix like/option like https://github.com/golang/go/pull/46714 to be accepted by the go maintainers.

func (*Loadtest) Run

func (lt *Loadtest) Run(ctx context.Context) (err_result error)

Run can only be called once per loadtest instance, it is stateful

func (*Loadtest) UpdateConfig

func (lt *Loadtest) UpdateConfig(cu ConfigUpdate) (handled bool)

UpdateConfig only returns false if the loadtest's run method has exited

This call can potentially block the caller on loadtest shutdown phase.

type LoadtestOption

type LoadtestOption func(*loadtestConfig)

type RetryChecker

type RetryChecker interface {
	CanRetry(ctx context.Context, workerID int, prevErr error) bool
}

type Retryer

type Retryer interface {
	Retry(ctx context.Context, workerID int, prevErr error) error
}

type StructuredLogger

type StructuredLogger interface {
	Debug(msg string, keysAndValues ...any)
	DebugContext(ctx context.Context, msg string, keysAndValues ...any)
	Warn(msg string, keysAndValues ...any)
	WarnContext(ctx context.Context, msg string, keysAndValues ...any)
	Error(msg string, keysAndValues ...any)
	ErrorContext(ctx context.Context, msg string, keysAndValues ...any)
	Info(msg string, keysAndValues ...any)
	InfoContext(ctx context.Context, msg string, keysAndValues ...any)
}

type TaskReader

type TaskReader interface {
	// ReadTasks fills the provided slice up to slice length starting at index 0 and returns how many records have been inserted
	//
	// Failing to fill the whole slice will signal the end of the loadtest.
	//
	// Note in general you should not use this behavior to signal loadtests to stop
	// if your loadtest needs to be time-bound. For that case you should signal a stop
	// via the context. This stop on failure to fill behavior only exists for cases
	// where the author wants to exhaustively run a set of tasks and not bound the
	// loadtest to a timespan but rather completeness of the tasks space.
	//
	// Note that if you have only partially filled the slice, those filled task slots
	// will still be run before termination of the loadtest.
	//
	// It is important to remember that if your loadtest loops around and you keep a large slice of
	// tasks in memory just to place small chunks of that list into the passed in slice of this function
	// that you could have a task executed by two separate goroutines at the same time under the right circumstances.
	// Therefore, it's really important that the tasks either be stateless or concrete copies of the original task object are
	// created when saved to the passed in slice of this function.
	ReadTasks([]Doer) int
}

TaskReader describes how to read tasks into a loadtest

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL