event

package module
v1.2.5 Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2023 License: BSD-3-Clause Imports: 5 Imported by: 0

README

event

Stars

event is a network I/O event notification library for Go. It uses epoll and kqueue to poll I/O events that is fast and low memory usage. It works in a similar manner as libevent.

The goal of event is to provide a BASIC tool for building high performance network applications.

Note: All development is done on a Raspberry Pi 4B.

Features

  • Supports Read/Write/Timeout events
  • Flexible timer event and ticker event
  • Supports event priority
  • Edge-triggered option
  • Simple API
  • Low memory usage

Getting Started

Installing

To start using event, just run go get:

$ go get -u github.com/cheng-zhongliang/event

Event

  • EvRead fires when the fd is readable.
  • EvWrite fires when the fd is writable.
  • EvTimeout fires when the timeout expires.

When the event is triggered, the callback function will be called.

Option

The event is one-shot by default. If you want to persist, you can set the EvPersist option.

ev := event.New(base, fd, event.EvRead|event.EvPersist, callback, arg)

The event is level-triggered by default. If you want to use edge-triggered, you can set the EvET option.

ev := event.New(base, fd, event.EvRead|event.EvET, callback, arg)

Read/Write/Timeout

These events can be used in combination.

base := event.NewBase()
ev := event.New(base, fd, event.EvRead|event.Timeout|event.EvPersist, callback, arg)
ev.Attach(time.Second)

When the fd is readable or timeout expires, this event will be triggered.

Timer

The timer is a one-shot event that will be triggered after the timeout expires.

base := event.NewBase()
ev := event.NewTimer(base, callback, arg)
ev.Attach(time.Second)

Ticker

The ticker is a repeating event that will be triggered every time the timeout expires.

base := event.NewBase()
ev := event.NewTicker(base, callback, arg)
ev.Attach(time.Second)

Priority

When events are triggered together, high priority events will be dispatched first.

ev := event.New(base, fd, event.EvRead|event.EvET, callback, arg)
ev.SetPriority(event.HPri)

Usage

Example echo server that binds to port 1246:

package main

import (
	"syscall"

	"github.com/cheng-zhongliang/event"
)

func main() {
	base, err := event.NewBase()
	if err != nil {
		panic(err)
	}

	fd := socket()
	ev := event.New(base, fd, event.EvRead|event.EvPersist, accept, base)
	if err := ev.Attach(0); err != nil {
		panic(err)
	}

	if err := base.Dispatch(); err != nil && err != syscall.EBADF {
		panic(err)
	}

	syscall.Close(fd)
}

func socket() int {
	addr := syscall.SockaddrInet4{Port: 1246, Addr: [4]byte{0, 0, 0, 0}}
	fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
	if err != nil {
		panic(err)
	}
	if err := syscall.Bind(fd, &addr); err != nil {
		panic(err)
	}
	err = syscall.Listen(fd, syscall.SOMAXCONN)
	if err != nil {
		panic(err)
	}
	return fd
}

func accept(fd int, events uint32, arg interface{}) {
	base := arg.(*event.EventBase)

	clientFd, _, err := syscall.Accept(fd)
	if err != nil {
		panic(err)
	}

	ev := event.New(base, clientFd, event.EvRead|event.EvPersist, echo, nil)
	if err := ev.Attach(0); err != nil {
		panic(err)
	}
}

func echo(fd int, events uint32, arg interface{}) {
	buf := make([]byte, 0xFFF)
	n, err := syscall.Read(fd, buf)
	if err != nil {
		panic(err)
	}
	if _, err := syscall.Write(fd, buf[:n]); err != nil {
		panic(err)
	}
}

Connect to the echo server:

$ telnet localhost 1246

Documentation

Index

Constants

View Source
const (
	// EvRead is readable event.
	EvRead = 1 << iota
	// EvWrite is writable event.
	EvWrite = 1 << iota
	// EvTimeout is timeout event.
	EvTimeout = 1 << iota

	// EvPersist is persistent behavior option.
	EvPersist = 1 << iota
	// EvET is edge-triggered behavior option.
	EvET = 1 << iota

	// EvLoopOnce is the flag to control event base loop just once.
	EvLoopOnce = 001
	// EvLoopNoblock is the flag to control event base loop not block.
	EvLoopNoblock = 002

	// HPri is the high priority.
	HPri eventPriority = 0b00
	// MPri is the middle priority.
	MPri eventPriority = 0b01
	// LPri is the low priority.
	LPri eventPriority = 0b10
)

Variables

View Source
var (
	ErrEventExists    = errors.New("event exists")
	ErrEventNotExists = errors.New("event does not exist")
	ErrEventInvalid   = errors.New("event invalid")
)

Functions

This section is empty.

Types

type Event

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

Event is the event to watch.

func New

func New(base *EventBase, fd int, events uint32, callback func(fd int, events uint32, arg interface{}), arg interface{}) *Event

New creates a new event with default priority MPri.

func NewTicker added in v1.2.2

func NewTicker(base *EventBase, callback func(fd int, events uint32, arg interface{}), arg interface{}) *Event

NewTicker creates a new ticker event.

func NewTimer added in v1.2.2

func NewTimer(base *EventBase, callback func(fd int, events uint32, arg interface{}), arg interface{}) *Event

NewTimer creates a new timer event.

func (*Event) Assign added in v1.2.2

func (ev *Event) Assign(base *EventBase, fd int, events uint32, callback func(fd int, events uint32, arg interface{}), arg interface{}, priority eventPriority)

Assign assigns the event. It is used to reuse the event. The event must be detached before it is assigned.

func (*Event) Attach added in v1.2.4

func (ev *Event) Attach(timeout time.Duration) error

Attach adds the event to the event base. Timeout is the timeout of the event. Default is 0, which means no timeout. But if EvTimeout is set in the event, the 0 represents expired immediately.

func (*Event) Base added in v1.2.4

func (ev *Event) Base() *EventBase

Base returns the event base of the event.

func (*Event) Detach added in v1.2.4

func (ev *Event) Detach() error

Detach deletes the event from the event base. The event will not be triggered after it is detached.

func (*Event) Events

func (ev *Event) Events() uint32

Events returns the events of the event.

func (*Event) Fd

func (ev *Event) Fd() int

Fd returns the file descriptor of the event.

func (*Event) Priority added in v1.2.4

func (ev *Event) Priority() eventPriority

Priority returns the priority of the event.

func (*Event) SetPriority added in v1.2.2

func (ev *Event) SetPriority(priority eventPriority)

SetPriority sets the priority of the event.

func (*Event) Timeout

func (ev *Event) Timeout() time.Duration

Timeout returns the timeout of the event.

type EventBase

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

EventBase is the base of all events.

func NewBase

func NewBase() (*EventBase, error)

NewBase creates a new event base.

func (*EventBase) Dispatch

func (bs *EventBase) Dispatch() error

Dispatch dispatches events. It will block until events trigger.

func (*EventBase) Loop added in v1.2.4

func (bs *EventBase) Loop(flags int) error

Loop loops events. Flags is the flags to control the loop behavior. Flags can be EvLoopOnce or EvLoopNoblock or both. If EvLoopOnce is set, the loop will just loop once. If EvLoopNoblock is set, the loop will not block.

func (*EventBase) Now added in v1.2.4

func (bs *EventBase) Now() time.Time

Now returns the cache of now time.

func (*EventBase) Shutdown added in v1.2.4

func (bs *EventBase) Shutdown() error

Shutdown breaks event loop and close the poll.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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