event
event copied to clipboard
Simple I/O event notification library wirtten in Golang
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
- 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.
Read/Write/Timeout
These events can be used in combination.
base := event.NewBase()
ev := event.New(base, fd, event.EvRead|event.Timeout, callback, arg)
ev.Attach(time.Second)
When the fd is readable or timeout expires, this event will be triggered.
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)
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, callback, arg)
ev.SetPriority(event.HP)
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