failover

package
v0.0.0-...-c93481c Latest Latest
Warning

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

Go to latest
Published: Nov 18, 2024 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrClosed error = errors.New("closed")

ErrClosed is returned by `Call` and `Subscribe` if the failover client is closed. It is also passed to `OnDisconnect()` if the connection was closed because the failover client was closed.

View Source
var ErrNoServers error = errors.New("No servers configured.")

ErrNoServers is used when no servers are configured, so no connection can be established. It is passed to `OnRetry()`.

Functions

func Call

func Call[C Client, R any](c *Failover[C], f func(client C) (R, error)) (R, error)

Call calls the passed function repeatedly with different servers until one of them returns the result without an error of type FailOverError. If all servers failed, there is a retry timeout and they are tried again.

If the failover client was closed before making the request, `ErrClosed` is returned. The server error is passed as-is if the failover client was closed while processing the request, or if the server returns an error that is not a FailOverError.

func CallAlwaysFailover

func CallAlwaysFailover[C Client, R any](c *Failover[C], f func(client C) (R, error)) (R, error)

CallAlwaysFailoveris like Call, but every error is treated as a FailoverError, trigger a failover. This function blocks forever until one of the servers delivers a non-error result, or the failover client was closed.

func Subscribe

func Subscribe[C Client, R any](
	c *Failover[C],
	subscriptionCall func(client C, result func(R, error)),
	result func(R, error))

Subscribe calls the passed `subscriptionCall` function repeatedly with different servers until one of them returns a result without an error of type FailOverError. If all servers failed, there is a retry timeout and they are tried again.

The passed function is a subscription registration function, It subscribes to notifications, with the notifications going to the `result` callback. If the result callback is called with an error of type FailOverError, failover happens automatically.

This subscription call is re-executed on each server that is connected.

If the failover client was closed before making the subscription request, `ErrClosed` is returned. The server error is passed as-is to the result callback if the failover client was closed, or if the server returns an error that is not a FailOverError.

func SubscribeAlwaysFailover

func SubscribeAlwaysFailover[C Client, R any](
	c *Failover[C],
	subscriptionCall func(client C, result func(R, error)),
	result func(R, error))

SubscribeAlwaysFailover is like Subscribe, but every error is treated as a FailOverError. The result callback is only called when one of the servers delivers a non-error result, or the failover client was closed.

Types

type Client

type Client interface {
	// f is installed as a callaback that can be called in case of asynchronous errors. Calling it
	// triggers a failover to another server.
	SetOnError(f func(error))
	// Close should close the client, stop all pending requests, wind down all goroutines, stop
	// sending notifications for subscriptions, etc.
	Close()
}

Client describes which methods a generic client must implement.

type Failover

type Failover[C Client] struct {
	// contains filtered or unexported fields
}

Failover is a generic client that is backed by multiple servers. If a server fails, there is an automatic failover to another server. If all servers fail, there is a retry timeout and all servers are tried again. Subscriptions are automatically re-subscribed on new servers.

func New

func New[C Client](opts *Options[C]) *Failover[C]

New creates a new failover client.

func (*Failover[C]) Close

func (f *Failover[C]) Close()

Close closes the failover client and closes the current client, resulting in `ErrClosed` in all future `Call` and `Subscribe` calls. It also calls `Close()` on the currently active client if one exists.

func (*Failover[C]) ManualReconnect

func (f *Failover[C]) ManualReconnect()

ManualReconnect triggers a manual reconnect, non-blocking. This re-tries connecting immediately without waiting for the retry timeout. We we are not currently disconnected, this is a no-op.

type FailoverError

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

FailoverError triggers a failover to another server. Other errors are passed through.

func NewFailoverError

func NewFailoverError(err error) *FailoverError

NewFailoverError wraps an error in a FailoverError.

func (*FailoverError) Error

func (f *FailoverError) Error() string

type Options

type Options[C Client] struct {
	Servers []*Server[C]
	// StartIndex returns an integer in the range `[0, len(Servers))` and defines the first server
	// to connect to. If `nil`, a random value is used for load balancing. This function will be
	// called only once.
	StartIndex func() int
	// RetryTimeout is the time we wait to retry any server after all servers failed had a
	// failure. If not specified, defaults to 15s.
	RetryTimeout time.Duration
	// OnConnect is called when a successful connection is established (when `server.Connect()` ran
	// without an error).
	OnConnect func(server *Server[C])
	// OnDisconnect is called when a running server connection is closed. The passed error is hte
	// error that caused the disconnect.
	OnDisconnect func(server *Server[C], err error)
	// OnRetry is called if all servers are not reachable or responded with an error. The passed
	// error is the last error that triggered a failover.
	OnRetry func(error)
}

Options for the failover client.

type Server

type Server[C Client] struct {
	// Name is a name of the server, useful for logging etc.
	Name string
	// Connect connects to the server.
	Connect func() (C, error)
}

Server are the server details.

func (*Server[C]) String

func (s *Server[C]) String() string

Jump to

Keyboard shortcuts

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