ultraclient

package module
v0.0.0-...-00e4b04 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2018 License: MIT Imports: 10 Imported by: 2

README

UltraClient

Ultra client is a wrapper around exisiting packages to provide loadbalancing, circuit breaking and backoffs for networking code in go. Rather than extend net/http you pass a function to ultraclient which accepts a url.URL, this allows you to use RPC based clients as well as net/http.

GoDoc

CircleCI

Usage

First create the ultraclient instance

lb := ultraclient.RoundRobinStrategy{}
bs := ultraclient.ExponentialBackoff{}
stats, _ := ultraclient.NewDogStatsD(url.URL{Host:"statsd:8125"})
endpoints := []url.URL{
  url.URL{Host: "server1:8080"},
  url.URL{Host: "server2:8080"},
}

config := loadbalancer.Config{
	Timeout:                50 * time.Millisecond,
	MaxConcurrentRequests:  500,
	ErrorPercentThreshold:  25,
	DefaultVolumeThreshold: 10,
  Retries:                100*time.Millisecond,
  Endpoints: endpoints,
	StatsD: loadbalancer.StatsD{
		Prefix: "application.client",
	},
}

client := ultraclient.NewClient(client, &lb, &bs)
client.RegisterStats(stats)

Then you can use it like so, this example shows how to use ultraclient with the http.Client


// When Do is called ultraclient will call the passed function with a url which has been returned from the loadbalancer
client.Do(func(uri string) error {
  resp, err := http.DefaultClient().Get(uri)
  if err != nil {
  	// If an error is returned ultraclient will re call the function based on the backoff and loadbalancer
	// configuration.
	// Should a particular uri raise so many errors that it open the circuit breaker then this uri will be 
	// removed from the load balancer and will not be used for future calls until the circuit half opens again.
  	return err
  }
  defer resp.Body.Close()
  ... do stuff
  return nil
})

Documentation

Index

Constants

View Source
const (
	// ErrorTimeout is a constant to be used for an error message when the client
	// experiences a timeout.
	ErrorTimeout = "timeout"

	// ErrorCircuitOpen is a constant to be used for an error message when the
	// client opens a circuit
	ErrorCircuitOpen = "circuit open"

	// ErrorGeneral is a constant to be used for an error message when the
	// client returns a general unhandled error.
	ErrorGeneral = "general error"

	// ErrorUnableToCompleteRequest is a constant to be used for an error message
	// when the client is unable to complete the request.
	ErrorUnableToCompleteRequest = "unable to complete request"
)
View Source
const (
	//StatsTiming is a statsD tag for timing metrics
	StatsTiming = "timing"
	// StatsCalled is a statsD tag to indicate a method has been called
	StatsCalled = "called"
	// StatsSuccess is a statsD tag to indicate operational success
	StatsSuccess = "success"
	// StatsRetry is a statsD tag to indicate the client will retry
	StatsRetry = "retry"
	// StatsError is a statsD tag to indicate that the client has resulted in
	// an error
	StatsError = "error"
	// StatsCircuitOpen is a statsD tag to indicate that the client has an open
	// circuit
	StatsCircuitOpen = "circuitopen"
	// StatsTimeout is a statsD tag to indicate that the operation has timed out
	StatsTimeout = "timeout"
)

Variables

This section is empty.

Functions

func PrettyPrintURL

func PrettyPrintURL(url *url.URL) string

PrettyPrintURL is a helper function to pretty print a url in a format suitable for statsd

Types

type Backoff

type Backoff interface {
}

Backoff is an interface which defines the backoff algorythim used by the retrier.

type BackoffStrategy

type BackoffStrategy interface {
	Create(retries int, delay time.Duration) []time.Duration
}

BackoffStrategy implements a strategy for retry backoffs

type Client

type Client interface {
	Do(work WorkFunc) error
	UpdateEndpoints([]url.URL)
	RegisterStats(stats Stats)
	Clone() Client
}

Client is an interface that defines the behaviour of an ultraclient

func NewClient

func NewClient(
	config Config,
	loadbalancingStrategy LoadbalancingStrategy,
	backoffStrategy BackoffStrategy) Client

NewClient creates a new instance of the loadbalancing client

type ClientError

type ClientError struct {
	// Message is the error message
	Message string

	// URL is the endpoint from which the message orginated
	URL url.URL
}

ClientError implements the Error interface and is a generic client error

func (ClientError) Error

func (s ClientError) Error() string

Error implements the error interface

type ClientImpl

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

ClientImpl is a loadbalancing client with configurable backoff and loadbalancing strategy, Client also implements circuit breaking for fail fast.

func (*ClientImpl) Clone

func (c *ClientImpl) Clone() Client

Clone creates a clone of the client and should be used to ensure that the loadbalancing is local to the current GoRoutine

func (*ClientImpl) Do

func (c *ClientImpl) Do(work WorkFunc) error

Do perfoms the work for the client, the WorkFunc passed as a parameter contains all your business logic to execute. The url from the loadbalancer is injected into the provided function. var response MyResponse

clientError := client.Do(func(endpoint url.URL) error {
  resp, err := http.DefaultClient.Get(endpoint)
  if err != nil {
    return err
  }

  response = resp // set the outer variable
  return nil
}

func (*ClientImpl) RegisterStats

func (c *ClientImpl) RegisterStats(stats Stats)

RegisterStats registers a stats interface with the client, multiple interfaces can be registered with a single client

func (*ClientImpl) UpdateEndpoints

func (c *ClientImpl) UpdateEndpoints(endpoints []url.URL)

UpdateEndpoints makes the given endpoints available to the loadbalancer

type Config

type Config struct {
	// Timeout is the length of time to wait before the work function times out
	Timeout time.Duration

	// MaxConcurrentRequests is the maximum number of work requests which can be
	// active at anyone time.
	MaxConcurrentRequests int

	// ErrorPercentThreshold is the percentage of work requests which result in
	// error before the circuit opens.
	ErrorPercentThreshold int

	//
	DefaultVolumeThreshold int

	// Retries is the number of times a request should be attempted before
	// returning.
	Retries int

	// RetryDelay is the default amount of time to wait before retrying the
	// work.
	RetryDelay time.Duration

	// Endpoints which are passed to the loadbalancing strategy and then to the
	// work function.
	Endpoints []url.URL

	// Enable statsd metrixs for client
	StatsD StatsD
}

Config defines the configuration for the Client

type DogStatsD

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

DogStatsD implements a StatsD metrics endpoint for which implements the DataDog statsd protocol

func NewDogStatsD

func NewDogStatsD(server url.URL) (*DogStatsD, error)

NewDogStatsD creates a new implementation of the DogStatsD metrics client

func NewDogStatsDWithClient

func NewDogStatsDWithClient(c *statsd.Client) *DogStatsD

NewDogStatsDWithClient creates a new implementation of the DogStatsD metrics client with an exiting client

func (*DogStatsD) Increment

func (d *DogStatsD) Increment(name string, tags []string, rate float64)

Increment sends a statsd message to increment a bucket to datadog

func (*DogStatsD) Timing

func (d *DogStatsD) Timing(name string, tags []string, duration time.Duration, rate float64)

Timing sends the execution time for the given function to statsd

type ExponentialBackoff

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

ExponentialBackoff is a backoffStrategy which implements an exponential retry policy

func (*ExponentialBackoff) Create

func (e *ExponentialBackoff) Create(retries int, delay time.Duration) []time.Duration

Create creates a new ExponentialBackoff timings with the given retries and iniital delay

type GetEndpoint

type GetEndpoint func() url.URL

GetEndpoint is a function that can be passed as a return parameter to the On call for NextEndpoint, this can be used to control which url is returned in your tests

type LoadbalancingStrategy

type LoadbalancingStrategy interface {
	// NextEndpoint returns the next endpoint in the strategy
	NextEndpoint() url.URL

	// SetEndpoints sets or updates the endpoints for the strategy
	SetEndpoints([]url.URL)

	// GetEndpoints returns the endpoints for the strategy
	GetEndpoints() []url.URL

	// Lenght returns the number of endpoints
	Length() int

	// Clone creates a deep clone of this object, rather than passing the main
	// instance to a client clone should be called which ensures that the
	// client obtains the correct behaviour for the loadbalancer.
	Clone() LoadbalancingStrategy
}

LoadbalancingStrategy is an interface to be implemented by loadbalancing strategies like round robin or random.

type MockBackoffStrategy

type MockBackoffStrategy struct {
	mock.Mock
}

MockBackoffStrategy is a mock implementation of the BackoffStrategy interface

func (*MockBackoffStrategy) Create

func (m *MockBackoffStrategy) Create(retries int, delay time.Duration) []time.Duration

Create is a mock implementation of Create

type MockClient

type MockClient struct {
	mock.Mock
}

MockClient implements a mock implementation of the ultraclient

func (*MockClient) Clone

func (m *MockClient) Clone() Client

Clone is the mock execution of the Clone method, returns self

func (*MockClient) Do

func (m *MockClient) Do(work WorkFunc) error

Do is the mock execution of the Do method mockClient.On("Do").Return(error, url)

func (*MockClient) RegisterStats

func (m *MockClient) RegisterStats(stats Stats)

RegisterStats is the mock execution of the RegisterStats method

func (*MockClient) UpdateEndpoints

func (m *MockClient) UpdateEndpoints(endpoints []url.URL)

UpdateEndpoints is a mock execution of the interface method

type MockCommand

type MockCommand struct {
	mock.Mock
}

MockCommand is a mock implementation of the Command interface This can be used for testing.

func (*MockCommand) Do

func (h *MockCommand) Do(url url.URL, input interface{}) (interface{}, error)

Do calls the internal mock and returns the values specified in the setup

type MockLoadbalancingStrategy

type MockLoadbalancingStrategy struct {
	mock.Mock
}

MockLoadbalancingStrategy is a mocked implementation of the Strategy interface for testing Usage: mock := MockLoadbalancingStrategy{} mock.On("NextEndpoint").Returns([]url.URL{url.URL{Host: ""}}) mock.On("SetEndpoints", mock.Anything) mock.AssertCalled(t, "NextEndpoint")

func (*MockLoadbalancingStrategy) Clone

Clone creates a clone of the current object

func (*MockLoadbalancingStrategy) GetEndpoints

func (m *MockLoadbalancingStrategy) GetEndpoints() []url.URL

GetEndpoints returns the current endpoint collection

func (*MockLoadbalancingStrategy) Length

func (m *MockLoadbalancingStrategy) Length() int

Length returns the number of endpoints

func (*MockLoadbalancingStrategy) NextEndpoint

func (m *MockLoadbalancingStrategy) NextEndpoint() url.URL

NextEndpoint returns the next endpoint in the list

func (*MockLoadbalancingStrategy) SetEndpoints

func (m *MockLoadbalancingStrategy) SetEndpoints(urls []url.URL)

SetEndpoints sets the mocks internal register with the given arguments, this method can not be used to update the return values in NextEndpoint.

type MockStats

type MockStats struct {
	mock.Mock
}

MockStats is a mock implementation of the Stats interface to be used for testing

func (*MockStats) Increment

func (m *MockStats) Increment(name string, tags []string, rate float64)

Increment is a mock implementation of the Stats interface

func (*MockStats) Timing

func (m *MockStats) Timing(name string, tags []string, duration time.Duration, rate float64)

Timing is a mock implementation of the Stats interface

type RandomStrategy

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

RandomStrategy implements Strategy for random endopoint selection

func (*RandomStrategy) Clone

Clone creates a clone of this strategy

func (*RandomStrategy) GetEndpoints

func (r *RandomStrategy) GetEndpoints() []url.URL

GetEndpoints returns a random endpoint

func (*RandomStrategy) Length

func (r *RandomStrategy) Length() int

Length returns the number of endpoints

func (*RandomStrategy) NextEndpoint

func (r *RandomStrategy) NextEndpoint() url.URL

NextEndpoint returns an endpoint using a random strategy

func (*RandomStrategy) SetEndpoints

func (r *RandomStrategy) SetEndpoints(endpoints []url.URL)

SetEndpoints sets the available endpoints for use by the strategy

type RoundRobinStrategy

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

RoundRobinStrategy is a load balancing strategy that implements a roundrobin style, it starts from a random location and the runs through each item in the endpoints collection sequentially

func (*RoundRobinStrategy) Clone

Clone creates a clone of this strategy this should be called when creating a new client

func (*RoundRobinStrategy) GetEndpoints

func (r *RoundRobinStrategy) GetEndpoints() []url.URL

GetEndpoints returns the next endpoint in the list

func (*RoundRobinStrategy) Length

func (r *RoundRobinStrategy) Length() int

Length returns the nuimber of endpoints

func (*RoundRobinStrategy) NextEndpoint

func (r *RoundRobinStrategy) NextEndpoint() url.URL

NextEndpoint returns an endpoint using a random strategy

func (*RoundRobinStrategy) SetEndpoints

func (r *RoundRobinStrategy) SetEndpoints(endpoints []url.URL)

SetEndpoints sets the available endpoints for use by the strategy

type Stats

type Stats interface {
	// Increment is a simple incremental counter for the given bucket
	// name is the name of the bucket to write to
	// tags is the list of tags to associate with the metric
	// rate is the rate to associate with the metric
	Increment(name string, tags []string, rate float64)

	// Timing records the duration of the given function
	// name is the name of the bucket to write to
	// tags is the list of tags to associate with the metric
	// duration is the duration for the call
	// rate is the rate to associate with the metric
	Timing(name string, tags []string, duration time.Duration, rate float64)
}

Stats is an interface which the concrete type will implement in order to send statistics to endpoints like StatsD or Logging

type StatsD

type StatsD struct {
	Prefix string
	Tags   []string
}

StatsD is the configuration for the StatsD endpoint

type WorkFunc

type WorkFunc func(endpoint url.URL) error

WorkFunc defines the work function to be passed to the Client.Do method

Jump to

Keyboard shortcuts

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