asyncserver

package
v0.0.0-...-7847555 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2018 License: CC0-1.0 Imports: 20 Imported by: 0

Documentation

Overview

Package asyncserver provides the framework for an async server.

This work is licensed under CC0 1.0 Universal (CC0 1.0), Public Domain Dedication. For details see:

http://creativecommons.org/publicdomain/zero/1.0/

Online go-documentation is available at:

https://godoc.org/bitbucket.org/pcas/serverutil/async/asyncserver

/////////////////////////////////////////////////////////////////////// server.go ///////////////////////////////////////////////////////////////////////

A Server listens for tasks on a specified connection and responds appropriately, with cancellation provided by a context ctx. So typical usage looks like:

ln, err := net.Listen("tcp", ":8080")

if err != nil {
	// handle error
}

s := asyncserver.New(timeouts)

for acceptingConnections {
	conn, err := ln.Accept()
	if err != nil {
		// handle error
	}
	// Typically some form of client handshake code goes here; this provides an
	// opportunity to determine the byte order e being used by the client.
	// ...
	// Handle the connection
	go s.HandleConnection(ctx, conn, e)
}

Here timeouts describes the *asyncserver.Timeout durations (and can be nil, in which case the default timeouts will be used), and ctx is a context.Context that can be used to terminate the client connection. Typically you will install a signal handler which, on catching a signal that indicates we should shut down, sets acceptingConnections to false and calls the cancel function for the context ctx.

Index

Constants

View Source
const (
	DefaultWait  = 30 * time.Minute
	DefaultRead  = 5 * time.Second
	DefaultWrite = 5 * time.Second
)

The default timeout durations.

Variables

View Source
var (
	ErrGracefulDisconnect    = errors.New("Graceful disconnection")          // ErrGracefulDisconnect indicates that a graceful disconnection was used to close the client connection.
	ErrTimeoutWaitingForTask = errors.New("Timeout whilst waiting for task") // ErrTimeoutWaitingForTask indicates that the server timed-out whilst waiting for a new task from the client.
)

Common errors.

Functions

This section is empty.

Types

type Client

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

Client describes a client.

func (*Client) ByteOrder

func (c *Client) ByteOrder() binary.ByteOrder

ByteOrder returns the byte order used in communication with the client.

func (*Client) Cancel

func (c *Client) Cancel(id async.TaskID)

Cancel cancels the task with given task id. If no task is currently assigned the given id, or if the corresponding task has already been cancelled, this does nothing.

func (*Client) CancelAll

func (c *Client) CancelAll()

CancelAll cancels all currently assigned tasks.

func (*Client) Close

func (c *Client) Close() error

Close is equivalent to Disconnect(0) and always returns nil.

func (*Client) Disconnect

func (c *Client) Disconnect(d time.Duration)

Disconnect begins a graceful disconnection. It will immediately call CloseRead on the underlying connection, and schedules a future Close on the connection after duration d has elapsed. Note that there is no way to cancel a graceful disconnection once started. If Disconnect is called again, then the final Close will be performed after the shortest of the two durations has expired. This is a non-blocking method.

func (*Client) LocalAddr

func (c *Client) LocalAddr() net.Addr

LocalAddr returns the local network address.

func (*Client) Log

func (c *Client) Log() log.Interface

Log returns the logger for the client.

func (*Client) Metadata

func (c *Client) Metadata(id async.TaskID) *async.TaskMetadata

Metadata returns the metadata for the given task id, or nil if no currently assigned task has this id.

func (*Client) Metrics

func (c *Client) Metrics() metrics.Interface

Metrics returns the metrics endpoint for the client.

func (*Client) RemoteAddr

func (c *Client) RemoteAddr() net.Addr

RemoteAddr returns the remote network address.

func (*Client) RunData

func (c *Client) RunData(id async.TaskID) interface{}

RunData returns the run data for the given task id, or nil if no currently assigned task has this id.

func (*Client) Server

func (c *Client) Server() *Server

Server returns the server handeling this client.

func (*Client) SetLogger

func (c *Client) SetLogger(lg log.Interface)

SetLogger sets the logger for this client. By default the logger is inherited from the server.

func (*Client) SetMetrics

func (c *Client) SetMetrics(m metrics.Interface)

SetMetrics sets the metrics endpoint for this client. By default this is inherited from the server.

func (*Client) String

func (c *Client) String() string

String returns a string description of the client of the form "remote addr->local addr".

func (*Client) TaskCodes

func (c *Client) TaskCodes() []serverutil.TaskCode

TaskCodes returns a slice of all assigned tasks codes. The task codes are sorted in assigned order, from oldest (at index 0) to most recent.

func (*Client) Tasks

func (c *Client) Tasks() []async.TaskID

Tasks returns a slice of all assigned task ids. The ids are distinct, and sorted in increasing order.

func (*Client) TasksWithTaskCode

func (c *Client) TasksWithTaskCode(t serverutil.TaskCode) []async.TaskID

TasksWithTaskCode returns a slice of all currently assigned task ids in the state with the given task code. The ids are distinct, and sorted in increasing order.

func (*Client) Timestamp

func (c *Client) Timestamp() time.Time

Timestamp returns the connection timestamp for the client.

type RunFunc

type RunFunc func(ctx context.Context, c *Client, id async.TaskID, lg log.Interface) (r io.Reader, err error)

RunFunc is the function that will run the task. It is the run function's responsibility to create the response data to send to a client.

Run functions are executed concurrently. Any run data returned by the originating task function can be recovered by passing the task id to the client's GetRunData method, e.g. d := c.GetRunData(id).

If no error is returned (i.e. if err == nil), then the success header

  • response code serverutil.OK (1 byte)
  • task ID (4 byte)

will be sent to the client, followed by the contents of the returned io.Reader r. The contents of r will be automatically encoded as per the definition of client-server communication before being sent to the client. If the copying of data from the io.Reader r to the client fails because of an error then the situation is serious: the client will be placed in an error state, and the connection will be dropped. If r satisfies the io.Closer interface then its Close() method will be called once copying stops (for whatever reason). If you do not need to send any data to the client, it is permitted for the returned io.Reader r to be nil.

If a non-nil error is returned then the reader r will be ignored. If err satisfies the serverutil.ErrorCoder interface, then

  • response code serverutil.Error (1 byte)
  • task ID (4 bytes)
  • error code (1 byte)

will be sent to the client, where the error code is given by err.ErrorCode(). If the returned error does not satisfy the serverutil.ErrorCoder interface then the situation is serious: the client will be placed in an error state, and the connection will be dropped.

type Server

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

Server handles async communication with clients.

func New

func New(timeout *Timeout) *Server

New returns a new server. If timeout is nil then the default timeout durations will be used. This satisfies the serverutil.Server interface.

func (*Server) Clients

func (s *Server) Clients() []serverutil.Client

Clients returns all client connections currently being handled by this server. The returned slice is sorted by increasing timestamp. Note: The underlying type of the entries in the returned slice is *Client.

func (*Server) Disconnect

func (s *Server) Disconnect(d time.Duration)

Disconnect calls the Disconnect method with duration d for each client currently being handled by this server.

func (*Server) HandleConnection

func (s *Server) HandleConnection(ctx context.Context, conn net.Conn, e binary.ByteOrder, args ...interface{}) error

HandleConnection handles tasks from the given connection conn using the given byte order e. Use the given context to trigger a graceful disconnection. The connection will be closed on return. The given args will be passed to the task functions.

func (*Server) Log

func (s *Server) Log() log.Interface

Log returns the logger for this server.

func (*Server) Metrics

func (s *Server) Metrics() metrics.Interface

Metrics returns the metrics endpoint for this server.

func (*Server) NumClients

func (s *Server) NumClients() (n int)

NumClients returns the number of client connections currently being handled by this server.

func (*Server) Register

func (s *Server) Register(t serverutil.TaskCode, f TaskFunc, name string)

Register registers a task function for the given task code. If a function is already registered for this task code, it will be replaced with the new function. The given name is used purely for logging purposes, and will be ignored if empty. This will panic if the task code is in the reserved range.

func (*Server) RegisteredTaskCodes

func (s *Server) RegisteredTaskCodes() []serverutil.TaskCode

RegisteredTaskCodes returns a slice of all currently registered task codes.

func (*Server) SetLogger

func (s *Server) SetLogger(l log.Interface)

SetLogger sets a logger.

func (*Server) SetMetrics

func (s *Server) SetMetrics(m metrics.Interface)

SetMetrics sets a metrics endpoint.

func (*Server) TaskFunc

func (s *Server) TaskFunc(t serverutil.TaskCode) (TaskFunc, string, bool)

TaskFunc returns the task function and name associated with the task code. The final return value is true iff a task function is associated with the task code.

func (*Server) Wait

func (s *Server) Wait()

Wait blocks until no client connections are being handled by this server.

type TaskFunc

type TaskFunc func(r binaryutil.BinaryReader, lg log.Interface, args ...interface{}) (f RunFunc, d interface{}, err error)

TaskFunc describes a task. It is the task function's responsibility to read the message data sent by a client.

The task function should do as little work as possible: only one task function per client can be executed at a time. The task function should return a run function f that will execute the task and return either the response data, or a error. If no run function needs to be called, the task function is free to return a nil-valued run function.

The task function may also return run data d. This optional data can be recovered at any time during the lifetime of the run function via the client's GetRunData method. Although typically data will be passed from the task function to the run function via a closure, it can sometimes be useful to store run-specific data in a publicly accessible way. The run data (if any) will become unavailable once the run function terminates.

If a non-nill error is returned then the run function f and run data d will be ignored. The client will be placed in an error state and the connection will be dropped. The task function should only return an error if the situation is serious.

type Timeout

type Timeout struct {
	Wait  time.Duration // Waiting for a new task.
	Read  time.Duration // Reading task data.
	Write time.Duration // Writing task data.
}

Timeout describes the various timeout durations when communicating with a client.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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