harmonic

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2020 License: Apache-2.0 Imports: 5 Imported by: 2

README

Harmonic Build Status GoDoc

Harmonic is the request dispatch algorithm powering ServiceQ (https://github.com/gptankit/serviceq). It is exposed in this repository as a package with enhanced support for initializing cluster state and error management.

Introduction

Assume a cluster of homogenous services that can serve user requests for a resource. One or more services might exhibit errors during their run ranging from connectivity loss, latency, misconfigurations and so on. Harmonic's role, in this scenario, is to select a service that has the best chance of processing an incoming request, thus improving the total probability of success for a group of requests.

How To Get

go get github.com/gptankit/harmonic

Then, import the module -

import "github.com/gptankit/harmonic"

How To Use

Harmonic works on user-supplied cluster state which includes a list of services (can be IP, fully-qualified URL or any unique identifier). By default, harmonic will zero the error count on each service and return a reference to cluster state, that can further be used to manage error counts.

// Initialize cluster state
serviceList := []string{"s0", "s1", "s2"}
cs, _ := harmonic.InitClusterState(serviceList)

// Call SelectService with retryIndex=0 and prevService=""
svc, _ := harmonic.SelectService(cs, 0, "")

The request can now be forwarded to the selected svc. Usually, the above call to SelectService should be enough to select a healthy service. If the request to svc succeedes, reset the error count -

// Reset error count for a service
cs.ResetError(svc)

As a good practice, it is advisable to do retries if the request to svc fails. The retry call to SelectService can be made after incrementing error count, incrementing retryIndex and passing previously selected svc -

// Increment error count for a service
cs.IncrementError(svc)
svc, _ := harmonic.SelectService(cs, 1, svc)

Note: What constitutes a success or failure response will depend on the type of application and use case, and needs to be defined accordingly by the application owner.

A complete example is added in sample folder.

Error Management

Listed are functions to manage error counts, and can be used depending on application needs -

func (cs *ClusterState) GetError(service string) (uint64, error)
func (cs *ClusterState) IncrementError(service string) error
func (cs *ClusterState) UpdateError(service string, errorcount uint64) error
func (cs *ClusterState) ResetError(service string) error
func (cs *ClusterState) ResetAllErrors() error

Benchmarks

Go bench results (env: linux/amd64)

Call to SelectService, first try -

Ops Time
2000 0.089s
20000 0.575s
200000 2.027s

Avg execution time: 8889 ns/op

Call to SelectService, retries -

Ops Time
5000 0.063s
50000 0.082s
500000 0.089s

Avg execution time: 32.4 ns/op

Feel free to play around and post feedbacks

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SelectService

func SelectService(cs *ClusterState, retryIndex int, prevService string) (string, error)

SelectService implements the routing logic to the cluster of downstream services. On first try, an error log lookup is done to determine the service-wise error count and effective error is calculated. If no error found for any service, random service selection (equal probability) is done, else weighted random service selection is done, where weights are inversely proportional to error count on the particular service. If the request to the selected service fails, round robin selection is done to deterministically select the next service.

Types

type ClusterState

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

func InitClusterState

func InitClusterState(serviceList []string) (*ClusterState, error)

InitClusterState initializes cluster state with user provided serviceList, and zeroing error for each service.

func (*ClusterState) GetError added in v0.3.0

func (cs *ClusterState) GetError(service string) (uint64, error)

GetError returns current errorcount for a service.

func (*ClusterState) GetServices added in v1.1.0

func (cs *ClusterState) GetServices() []string

GetServices returns current list of services.

func (*ClusterState) IncrementError

func (cs *ClusterState) IncrementError(service string) error

IncrementError increments errorcount by 1 for a service.

func (*ClusterState) ResetAllErrors

func (cs *ClusterState) ResetAllErrors() error

ResetAllErrors resets errorcount for all services.

func (*ClusterState) ResetError

func (cs *ClusterState) ResetError(service string) error

ResetError resets errorcount for a service.

func (*ClusterState) UpdateError

func (cs *ClusterState) UpdateError(service string, errorcount uint64) error

UpdateError updates user provided errorcount for a service.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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