netpoll

package
v0.0.0-...-054e3a2 Latest Latest
Warning

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

Go to latest
Published: Dec 31, 2019 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package netpoll provides a portable interface for network I/O event notification facility.

Its API is intended for monitoring multiple file descriptors to see if I/O is possible on any of them. It supports edge-triggered and level-triggered interfaces.

To get more info you could look at operating system API documentation of particular netpoll implementations:

  • epoll on linux;
  • kqueue on bsd;

The Handle function creates netpoll.Desc for further use in Poller's methods:

desc, err := netpoll.Handle(conn, netpoll.EventRead | netpoll.EventEdgeTriggered)
if err != nil {
	// handle error
}

The Poller describes os-dependent network poller:

poller, err := netpoll.New(nil)
if err != nil {
	// handle error
}

// Get netpoll descriptor with EventRead|EventEdgeTriggered.
desc := netpoll.Must(netpoll.HandleRead(conn))

poller.Start(desc, func(ev netpoll.Event) {
	if ev&netpoll.EventReadHup != 0 {
		poller.Stop(desc)
		conn.Close()
		return
	}

	_, err := ioutil.ReadAll(conn)
	if err != nil {
		// handle error
	}
})

Currently, Poller is implemented only for Linux.

Index

Constants

View Source
const (
	EPOLLIN      = unix.EPOLLIN
	EPOLLOUT     = unix.EPOLLOUT
	EPOLLRDHUP   = unix.EPOLLRDHUP
	EPOLLPRI     = unix.EPOLLPRI
	EPOLLERR     = unix.EPOLLERR
	EPOLLHUP     = unix.EPOLLHUP
	EPOLLET      = unix.EPOLLET
	EPOLLONESHOT = unix.EPOLLONESHOT
)

EpollEvents that are mapped to epoll_event.events possible values.

View Source
const (
	// EventHup is indicates that some side of i/o operations (receive, send or
	// both) is closed.
	// Usually (depending on operating system and its version) the EventReadHup
	// or EventWriteHup are also set int Event value.
	EventHup Event = 0x10

	EventReadHup  = 0x20
	EventWriteHup = 0x40

	EventErr = 0x80

	// EventPollerClosed is a special Event value the receipt of which means that the
	// Poller instance is closed.
	EventPollerClosed = 0x8000
)

Event values that could be passed to CallbackFn as additional information event.

Variables

View Source
var (
	// ErrNotFiler is returned by Handle* functions to indicate that given
	// net.Conn does not provide access to its file descriptor.
	ErrNotFiler = fmt.Errorf("could not get file descriptor")

	// ErrClosed is returned by Poller methods to indicate that instance is
	// closed and operation could not be processed.
	ErrClosed = fmt.Errorf("poller instance is closed")

	// ErrRegistered is returned by Poller Start() method to indicate that
	// connection with the same underlying file descriptor was already
	// registered within the poller instance.
	ErrRegistered = fmt.Errorf("file descriptor is already registered in poller instance")

	// ErrNotRegistered is returned by Poller Stop() and Resume() methods to
	// indicate that connection with the same underlying file descriptor was
	// not registered before within the poller instance.
	ErrNotRegistered = fmt.Errorf("file descriptor was not registered before in poller instance")
)
View Source
var ErrScheduleTimeout = fmt.Errorf("schedule error: timed out")

ErrScheduleTimeout returned by Grpool to indicate that there no free goroutines during some period of time.

Functions

func GoID

func GoID() int

Types

type CallbackFn

type CallbackFn func(Event)

CallbackFn is a function that will be called on kernel i/o event notification.

type Config

type Config struct {
	// OnWaitError will be called from goroutine, waiting for events.
	OnWaitError func(error)
}

Config contains options for Poller configuration.

type Desc

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

Desc is a network connection within netpoll descriptor. It's methods are not goroutine safe.

func Handle

func Handle(conn net.Conn, event Event) (*Desc, error)

Handle creates new Desc with given conn and event. Returned descriptor could be used as argument to Start(), Resume() and Stop() methods of some Poller implementation.

func HandleListener

func HandleListener(ln net.Listener, event Event) (*Desc, error)

HandleListener returns descriptor for a net.Listener.

func HandleRead

func HandleRead(conn net.Conn) (*Desc, error)

HandleRead creates read descriptor for further use in Poller methods. It is the same as Handle(conn, EventRead|EventEdgeTriggered).

func HandleReadOnce

func HandleReadOnce(conn net.Conn) (*Desc, error)

HandleReadOnce creates read descriptor for further use in Poller methods. It is the same as Handle(conn, EventRead|EventOneShot).

func HandleReadWrite

func HandleReadWrite(conn net.Conn) (*Desc, error)

HandleReadWrite creates read and write descriptor for further use in Poller methods. It is the same as Handle(conn, EventRead|EventWrite|EventEdgeTriggered).

func HandleWrite

func HandleWrite(conn net.Conn) (*Desc, error)

HandleWrite creates write descriptor for further use in Poller methods. It is the same as Handle(conn, EventWrite|EventEdgeTriggered).

func HandleWriteOnce

func HandleWriteOnce(conn net.Conn) (*Desc, error)

HandleWriteOnce creates write descriptor for further use in Poller methods. It is the same as Handle(conn, EventWrite|EventOneShot).

func Must

func Must(desc *Desc, err error) *Desc

Must is a helper that wraps a call to a function returning (*Desc, error). It panics if the error is non-nil and returns desc if not. It is intended for use in short Desc initializations.

func NewDesc

func NewDesc(fd uintptr, ev Event) *Desc

NewDesc creates descriptor from custom fd.

func (*Desc) Close

func (h *Desc) Close() error

Close closes underlying file.

type Epoll

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

Epoll represents single epoll instance.

func EpollCreate

func EpollCreate(c *EpollConfig) (*Epoll, error)

EpollCreate creates new epoll instance. It starts the wait loop in separate goroutine.

func (*Epoll) Add

func (ep *Epoll) Add(fd int, events EpollEvent, cb func(EpollEvent)) (err error)

Add adds fd to epoll set with given events. Callback will be called on each received event from epoll. Note that _EPOLLCLOSED is triggered for every cb when epoll closed.

func (*Epoll) Close

func (ep *Epoll) Close() (err error)

Close stops wait loop and closes all underlying resources.

func (*Epoll) Del

func (ep *Epoll) Del(fd int) (err error)

Del removes fd from epoll set.

func (*Epoll) Mod

func (ep *Epoll) Mod(fd int, events EpollEvent) (err error)

Mod sets to listen events on fd.

type EpollConfig

type EpollConfig struct {
	// OnWaitError will be called from goroutine, waiting for events.
	OnWaitError func(error)
}

EpollConfig contains options for Epoll instance configuration.

type EpollEvent

type EpollEvent uint32

EpollEvent represents epoll events configuration bit mask.

func (EpollEvent) String

func (evt EpollEvent) String() (str string)

String returns a string representation of EpollEvent.

type Event

type Event uint16

Event represents netpoll configuration bit mask.

const (
	EventRead  Event = 0x1
	EventWrite       = 0x2
)

Event values that denote the type of events that caller want to receive.

const (
	EventOneShot       Event = 0x4
	EventEdgeTriggered       = 0x8
)

Event values that configure the Poller's behavior.

func (Event) String

func (ev Event) String() (str string)

String returns a string representation of Event.

type Grpoolx

type Grpoolx struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

func NewGrpoolx

func NewGrpoolx(max int, min int, idle time.Duration, busy time.Duration) *Grpoolx

NewGrpoolx create new Grpoolx with min goroutines initionated, and max goroutine limited. When a goroutine was idled ,then kill it. When all goroutines are buse and count between min and max ,a task will be scheduled to a new goroutine,or get ErrScheduleTimeout

func (*Grpoolx) Schedule

func (g *Grpoolx) Schedule(task *Task) error

func (*Grpoolx) ScheduleTimeout

func (g *Grpoolx) ScheduleTimeout(timeout time.Duration, task *Task) error

type Poller

type Poller interface {
	// Start adds desc to the observation list.
	//
	// Note that if desc was configured with OneShot event, then poller will
	// remove it from its observation list. If you will be interested in
	// receiving events after the callback, call Resume(desc).
	//
	// Note that Resume() call directly inside desc's callback could cause
	// deadlock.
	//
	// Note that multiple calls with same desc will produce unexpected
	// behavior.
	Start(*Desc, CallbackFn) error

	// Stop removes desc from the observation list.
	//
	// Note that it does not call desc.Close().
	Stop(*Desc) error

	// Resume enables observation of desc.
	//
	// It is useful when desc was configured with EventOneShot.
	// It should be called only after Start().
	//
	// Note that if there no need to observe desc anymore, you should call
	// Stop() to prevent memory leaks.
	Resume(*Desc) error
}

Poller describes an object that implements logic of polling connections for i/o events such as availability of read() or write() operations.

func New

func New(c *Config) (Poller, error)

New creates new epoll-based Poller instance with given config.

func NewWithGrpoolx

func NewWithGrpoolx(c *Config, grp *Grpoolx, tkp *Taskpool) (Poller, error)

New creates new epoll-based Poller instance with given config.

type Task

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

type Taskpool

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

Timerpool provides GC-able pooling of *time.Timer's. can be used by multiple goroutines concurrently.

func (*Taskpool) Get

func (tp *Taskpool) Get(fn func(EpollEvent), e EpollEvent) *Task

Get returns a timer that completes after the given duration.

func (*Taskpool) Put

func (tp *Taskpool) Put(t *Task)

Put pools the given timer.

There is no need to call t.Stop() before calling Put.

Put will try to stop the timer before pooling. If the given timer already expired, Put will read the unreceived value if there is one.

type Timerpool

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

Timerpool provides GC-able pooling of *time.Timer's. can be used by multiple goroutines concurrently.

func (*Timerpool) Get

func (tp *Timerpool) Get(d time.Duration) *time.Timer

Get returns a timer that completes after the given duration.

func (*Timerpool) Put

func (tp *Timerpool) Put(t *time.Timer)

Put pools the given timer.

There is no need to call t.Stop() before calling Put.

Put will try to stop the timer before pooling. If the given timer already expired, Put will read the unreceived value if there is one.

Jump to

Keyboard shortcuts

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