gate

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2024 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package gate implements a simple atomic boolean that controls access to HTTP client or server functionality

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// Closed is the optional round tripper invoked when the gate is closed.  If this
	// field is unset, then a nil *http.Response and a *ClosedError are returned when
	// the gate status indicates closed.
	Closed http.RoundTripper

	// Gate is the Status that indicates whether a gate allows traffic.  If this field
	// is unset, this middleware is a nop.
	Gate Status
}

Client defines a clientside middleware that controls access to round trippers based upon a gate status

func (Client) Then added in v0.1.2

func (c Client) Then(next http.RoundTripper) http.RoundTripper

Then decorates a round tripper so that it is controlled by the Gate field.

The returned http.RoundTripper will always supply a CloseIdleConnections method. If next also supplies that method, it will be invoked whenever the decorator's method is invoked. Otherwise, the decorator's CloseIdleConnections will do nothing.

For consistency with other libraries, if next is nil then http.DefaultTransport is used as the decorated round tripper.

type ClosedError

type ClosedError struct {
	// Gate represents the gate instance that was closed at the time of the error.
	// Note that this gate may have been opened in the time that a caller waited on
	// the call to produce this error.
	Gate Status
}

ClosedError is returned by any decorated infrastructure to indicate that the gate disallowed the client request.

func (*ClosedError) Error

func (ce *ClosedError) Error() string

Error satisfies the error interface

type Config

type Config struct {
	// Name is an optional identifier for this gate.  The Gate itself does not make
	// use of this value.  It's purely for distinguishing gates when an application
	// uses more than one (1) gate.
	Name string

	// InitiallyClosed indicates the state of a Gate when it is created.  The default
	// is to create a Gate that is open.  If this field is true, the Gate is created
	// in the closed state.
	InitiallyClosed bool

	// Hooks is the optional set of preregistered callbacks when a gate is created with this
	// configuration.  Any empty hooks are silently ignored.
	//
	// Any callbacks that match the initial state of the gate, e.g. OnOpen when InitiallyClosed
	// is false, are immediately invoked before New returns.
	Hooks Hooks
}

Config describes all the various configurable settings for creating a Gate

type Control

type Control interface {
	// Open raises this gate to allow traffic.  This method is atomic and idempotent.  It returns
	// true if there was a state change, false to indicate the gate was already open.
	Open() bool

	// Close lowers this gate to reject traffic.  This method is atomic and idempotent.  It returns
	// true if there was a state change, false to indicate the gate was already closed.
	Close() bool

	// Register adds a tuple of callbacks to this status instance.  If the given Hook
	// has no callbacks set, this method does nothing.
	//
	// Callbacks registered for the current state, e.g. OnOpen registered against an open gate,
	// will be immediately invoked prior to this method returning.
	Register(Hook)
}

Control allows a gate to be open and closed atomically. All methods of this interface are safe for concurrent access.

All methods of this interface mutate the underlying gate and thus involve synchronization. In particular, Register is atomic with respect to Open/Close.

type ControlHandler

type ControlHandler struct {
	// StateChange is the required strategy for determining how to change a gate
	// given an HTTP request.  This closure can examine any aspect of the request, e.g.
	// URL parameters, request URI, etc, to determine what state change should occur.
	//
	// This closure can return StateNoChange to indicate that the handler should do nothing
	// to a gate.  For example, the request may fail a security permissions check.
	StateChange func(*http.Request) StateChange

	// Gate is the required gate control instance used to open and close the gate
	Gate Control
}

ControlHandler is an http.Handler that allows HTTP requests to open or close a gate

func (ControlHandler) ServeHTTP

func (ch ControlHandler) ServeHTTP(response http.ResponseWriter, request *http.Request)

ServeHTTP invokes the StateChange closure and takes the appropriate action

type Hook

type Hook struct {
	// OnOpen is invoked any time a gate is opened.  If a gate is open when this callback
	// is registered, it will be immediately invoked.
	//
	// Note: Callbacks should never modify the gate.  The Status instance passed to all callbacks
	// is not castable to Control.
	OnOpen func(Status)

	// OnClose is invoked any time a gate is closed.  If a gate is closed when this
	// callback is registered, it will be immediately invoked.
	//
	// Note: Callbacks should never modify the gate.  The Status instance passed to all callbacks
	// is not castable to Control.
	OnClosed func(Status)
}

Hook is a tuple of callbacks for gate state

type Hooks

type Hooks []Hook

Hooks is a simple slice type for Hook instances

type Interface

type Interface interface {
	Status
	Control
}

Interface represents a gate. Instances are created via New.

func New

func New(c Config) Interface

New produces a gate from a set of options. The returned instance will be in the state indicated by Config.InitiallyClosed.

type Server

type Server struct {
	// Closed is the optional handler to be invoked with the gate is closed.
	// If this field is not set, http.StatusServiceUnavailable is written
	// to the response.
	//
	// A convenient, configurable handler for this field is httpaux.ConstantHandler.
	Closed http.Handler

	// Gate is the Status that indicates whether a gate allows traffic.  If this field
	// is unset, this middleware is a nop.
	Gate Status
}

Server defines a serverside middleware that controls access to handlers based upon a gate status

func (Server) Then

func (s Server) Then(next http.Handler) http.Handler

Then decorates a handler so that it is controlled by the Gate field. Next is required and cannot be nil, or a panic will result.

type StateChange

type StateChange int

StateChange indicates what to do to a gate

const (
	// StateNoChange indicates that no control operation should be performed
	StateNoChange StateChange = iota

	// StateOpen indicates that the gate should be opened
	StateOpen

	// StateClose indicates that the gate should be closed
	StateClose
)

type Status

type Status interface {
	// Name is an optional identifier for this atomic boolean.  No guarantees
	// as to uniqueness are made.  This value is completely up to client configuration.
	//
	// A non-empty name is often useful when an application uses multiple gates.  This
	// name can be used in log files, metrics, etc.
	Name() string

	// IsOpen checks if this instance is open and thus allowing traffic
	IsOpen() bool
}

Status is implemented by anything that can check an atomic boolean. All methods of this interface are safe for concurrent access. None of the methods in this interface mutate the underlying gate.

Note: although New returns a type that also implements this interface, Status instances passed to callbacks ARE NOT castable to Control. This prevents modification of the gate by callbacks.

Jump to

Keyboard shortcuts

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