Documentation
¶
Index ¶
- Constants
- Variables
- func GetBoundDevice(fd int) (string, error)
- func NewAsyncAdapter(ioc *IO, sc syscall.Conn, rw io.ReadWriter, cb AsyncAdapterHandler, ...)
- type AcceptCallback
- type AcceptPacketCallback
- type AsyncAdapter
- func (a *AsyncAdapter) AsyncClose(cb func(err error))
- func (a *AsyncAdapter) AsyncRead(b []byte, cb AsyncCallback)
- func (a *AsyncAdapter) AsyncReadAll(b []byte, cb AsyncCallback)
- func (a *AsyncAdapter) AsyncWrite(b []byte, cb AsyncCallback)
- func (a *AsyncAdapter) AsyncWriteAll(b []byte, cb AsyncCallback)
- func (a *AsyncAdapter) Cancel()
- func (a *AsyncAdapter) Close() error
- func (a *AsyncAdapter) Closed() bool
- func (a *AsyncAdapter) RawFd() int
- func (a *AsyncAdapter) Read(b []byte) (int, error)
- func (a *AsyncAdapter) Slot() *internal.Slot
- func (a *AsyncAdapter) Write(b []byte) (int, error)
- type AsyncAdapterHandler
- type AsyncCallback
- type AsyncCanceller
- type AsyncReadCallbackPacket
- type AsyncReadStream
- type AsyncReadWriter
- type AsyncReader
- type AsyncReaderFrom
- type AsyncStream
- type AsyncWriteCallbackPacket
- type AsyncWriteStream
- type AsyncWriter
- type AsyncWriterTo
- type BipBuffer
- func (buf *BipBuffer) Claim(n int) []byte
- func (buf *BipBuffer) Claimed() int
- func (buf *BipBuffer) Commit(n int) []byte
- func (buf *BipBuffer) Committed() int
- func (buf *BipBuffer) Consume(n int)
- func (buf *BipBuffer) Empty() bool
- func (buf *BipBuffer) Head() []byte
- func (buf *BipBuffer) Prefault()
- func (buf *BipBuffer) Reset()
- func (buf *BipBuffer) Size() int
- func (buf *BipBuffer) Wrapped() bool
- type ByteBuffer
- func (b *ByteBuffer) AsyncReadFrom(r AsyncReader, cb AsyncCallback)
- func (b *ByteBuffer) AsyncWriteTo(w AsyncWriter, cb AsyncCallback)
- func (b *ByteBuffer) Cap() int
- func (b *ByteBuffer) Claim(fn func(b []byte) int)
- func (b *ByteBuffer) ClaimFixed(n int) (claimed []byte)
- func (b *ByteBuffer) Commit(n int)
- func (b *ByteBuffer) Consume(n int)
- func (b *ByteBuffer) Data() []byte
- func (b *ByteBuffer) Discard(slot Slot) (discarded int)
- func (b *ByteBuffer) DiscardAll()
- func (b *ByteBuffer) Len() int
- func (b *ByteBuffer) Prefault()
- func (b *ByteBuffer) PrepareRead(n int) (err error)
- func (b *ByteBuffer) Read(dst []byte) (int, error)
- func (b *ByteBuffer) ReadByte() (byte, error)
- func (b *ByteBuffer) ReadFrom(r io.Reader) (int64, error)
- func (b *ByteBuffer) ReadLen() int
- func (b *ByteBuffer) Reserve(n int)
- func (b *ByteBuffer) Reserved() int
- func (b *ByteBuffer) Reset()
- func (b *ByteBuffer) Save(n int) (slot Slot)
- func (b *ByteBuffer) SaveLen() int
- func (b *ByteBuffer) Saved() []byte
- func (b *ByteBuffer) SavedSlot(slot Slot) []byte
- func (b *ByteBuffer) ShrinkBy(n int) int
- func (b *ByteBuffer) ShrinkTo(n int) (shrunkBy int)
- func (b *ByteBuffer) UnreadByte() error
- func (b *ByteBuffer) Write(bb []byte) (int, error)
- func (b *ByteBuffer) WriteByte(bb byte) error
- func (b *ByteBuffer) WriteLen() int
- func (b *ByteBuffer) WriteString(s string) (int, error)
- func (b *ByteBuffer) WriteTo(w io.Writer) (int64, error)
- type Codec
- type CodecConn
- func (c *CodecConn[Enc, Dec]) AsyncReadNext(cb func(error, Dec))
- func (c *CodecConn[Enc, Dec]) AsyncWriteNext(item Enc, cb AsyncCallback)
- func (c *CodecConn[Enc, Dec]) Close() error
- func (c *CodecConn[Enc, Dec]) NextLayer() Stream
- func (c *CodecConn[Enc, Dec]) ReadNext() (Dec, error)
- func (c *CodecConn[Enc, Dec]) WriteNext(item Enc) (n int, err error)
- type Conn
- type Decoder
- type Encoder
- type File
- type FileDescriptor
- type IO
- func (ioc *IO) Close() error
- func (ioc *IO) Closed() bool
- func (ioc *IO) Deregister(slot *internal.Slot)
- func (ioc *IO) Pending() int64
- func (ioc *IO) Poll() error
- func (ioc *IO) PollOne() (n int, err error)
- func (ioc *IO) Post(handler func()) error
- func (ioc *IO) Posted() int
- func (ioc *IO) Register(slot *internal.Slot)
- func (ioc *IO) Run() error
- func (ioc *IO) RunOne() (err error)
- func (ioc *IO) RunOneFor(dur time.Duration) (err error)
- func (ioc *IO) RunPending() error
- func (ioc *IO) RunWarm(busyCycles int, timeout time.Duration) (err error)
- func (ioc *IO) SetRead(slot *internal.Slot) error
- func (ioc *IO) SetWrite(slot *internal.Slot) error
- func (ioc *IO) UnsetRead(slot *internal.Slot) error
- func (ioc *IO) UnsetReadWrite(slot *internal.Slot) error
- func (ioc *IO) UnsetWrite(slot *internal.Slot) error
- type Listener
- type PacketConn
- type Slot
- type SlotOffsetter
- type SlotSequencer
- func (s *SlotSequencer) Bytes() int
- func (s *SlotSequencer) FillPct() float64
- func (s *SlotSequencer) MaxBytes() int
- func (s *SlotSequencer) Pop(seq int) (Slot, bool)
- func (s *SlotSequencer) Push(seq int, slot Slot) (ok bool, err error)
- func (s *SlotSequencer) Reset()
- func (s *SlotSequencer) Size() int
- type Socket
- func (s *Socket) Bind(addrPort netip.AddrPort) error
- func (s *Socket) BindToDevice(name string) (*net.Interface, error)
- func (s *Socket) BoundDevice() *net.Interface
- func (s *Socket) Close() (err error)
- func (s *Socket) IsNonblocking() (bool, error)
- func (s *Socket) RawFd() int
- func (s *Socket) RecvFrom(b []byte, flags SocketIOFlags) (n int, peerAddr netip.AddrPort, err error)
- func (s *Socket) ReuseAddr(reuse bool) error
- func (s *Socket) ReusePort(reuse bool) error
- func (s *Socket) SendTo(b []byte, flags SocketIOFlags, peerAddr netip.AddrPort) (int, error)
- func (s *Socket) SetNoDelay(delay bool) error
- func (s *Socket) SetNonblocking(nonblocking bool) error
- func (s *Socket) UnbindFromDevice() error
- type SocketDomain
- type SocketIOFlags
- type SocketProtocol
- type SocketType
- type Stream
- type SyncReadStream
- type SyncStream
- type SyncWriteStream
- type Timer
Constants ¶
const ( WarmDefaultBusyCycles = 10 WarmDefaultTimeout = time.Millisecond )
const MaxCallbackDispatch int = 32
MaxCallbackDispatch is the maximum number of callbacks that can exist on a stack-frame when asynchronous operations can be completed immediately.
This is the limit to the `IO.dispatched` counter.
Variables ¶
var ErrNoSpaceLeftForSlot = errors.New(
"no space left to buffer the given slot",
)
Functions ¶
func GetBoundDevice ¶
func NewAsyncAdapter ¶
func NewAsyncAdapter( ioc *IO, sc syscall.Conn, rw io.ReadWriter, cb AsyncAdapterHandler, opts ...sonicopts.Option, )
NewAsyncAdapter takes in an IO instance and an interface of syscall.Conn and io.ReadWriter pertaining to the same object and invokes a completion handler which:
- provides the async adapter on successful completion
- provides an error if any occurred when async-adapting the provided object
See async_adapter_test.go for examples on how to setup an AsyncAdapter.
Types ¶
type AcceptCallback ¶
type AcceptPacketCallback ¶
type AcceptPacketCallback func(error, PacketConn)
type AsyncAdapter ¶
type AsyncAdapter struct {
// contains filtered or unexported fields
}
AsyncAdapter is a wrapper around syscall.Conn which enables clients to schedule async read and write operations on the underlying file descriptor.
func (*AsyncAdapter) AsyncClose ¶
func (a *AsyncAdapter) AsyncClose(cb func(err error))
func (*AsyncAdapter) AsyncRead ¶
func (a *AsyncAdapter) AsyncRead(b []byte, cb AsyncCallback)
AsyncRead reads data from the underlying file descriptor into b asynchronously.
AsyncRead returns no error on short reads. If you want to ensure that the provided buffer is completely filled, use AsyncReadAll.
func (*AsyncAdapter) AsyncReadAll ¶
func (a *AsyncAdapter) AsyncReadAll(b []byte, cb AsyncCallback)
AsyncReadAll reads data from the underlying file descriptor into b asynchronously.
The provided handler is invoked in the following cases:
- an error occurred
- the provided buffer has been fully filled after zero or several underlying read(...) operations.
func (*AsyncAdapter) AsyncWrite ¶
func (a *AsyncAdapter) AsyncWrite(b []byte, cb AsyncCallback)
AsyncWrite writes data from the supplied buffer to the underlying file descriptor asynchronously.
AsyncWrite returns no error on short writes. If you want to ensure that the provided buffer is completely written, use AsyncWriteAll.
func (*AsyncAdapter) AsyncWriteAll ¶
func (a *AsyncAdapter) AsyncWriteAll(b []byte, cb AsyncCallback)
AsyncWriteAll writes data from the supplied buffer to the underlying file descriptor asynchronously.
The provided handler is invoked in the following cases:
- an error occurred
- the provided buffer has been fully written after zero or several underlying write(...) operations.
func (*AsyncAdapter) Cancel ¶
func (a *AsyncAdapter) Cancel()
Cancel cancels any asynchronous operations scheduled on the underlying file descriptor.
func (*AsyncAdapter) Close ¶
func (a *AsyncAdapter) Close() error
func (*AsyncAdapter) Closed ¶
func (a *AsyncAdapter) Closed() bool
func (*AsyncAdapter) RawFd ¶
func (a *AsyncAdapter) RawFd() int
func (*AsyncAdapter) Read ¶
func (a *AsyncAdapter) Read(b []byte) (int, error)
Read reads data from the underlying file descriptor into b.
func (*AsyncAdapter) Slot ¶
func (a *AsyncAdapter) Slot() *internal.Slot
type AsyncAdapterHandler ¶
type AsyncAdapterHandler func(error, *AsyncAdapter)
type AsyncCallback ¶
type AsyncCanceller ¶
type AsyncCanceller interface {
// Cancel cancells all asynchronous operations on the next layer.
Cancel()
}
type AsyncReadStream ¶
type AsyncReadStream interface { AsyncReader AsyncCanceller io.Closer }
type AsyncReadWriter ¶
type AsyncReadWriter interface { AsyncReader AsyncWriter }
type AsyncReader ¶
type AsyncReader interface { // AsyncRead reads up to `len(b)` bytes into `b` asynchronously. // // This call should not block. The provided completion handler is called in the following cases: // - a read of up to `n` bytes completes // - an error occurs // // Callers should always process the returned bytes before considering the error err. Implementations of AsyncRead // are discouraged from invoking the handler with 0 bytes and a nil error. // // Ownership of the byte slice must be retained by callers, which must guarantee that it remains valid until the // callback is invoked. AsyncRead(b []byte, cb AsyncCallback) // AsyncReadAll reads exactly `len(b)` bytes into b asynchronously. AsyncReadAll(b []byte, cb AsyncCallback) }
AsyncReader is the interface that wraps the AsyncRead and AsyncReadAll methods.
type AsyncReaderFrom ¶
type AsyncReaderFrom interface {
AsyncReadFrom(AsyncReader, AsyncCallback)
}
type AsyncStream ¶
type AsyncStream interface { AsyncReadStream AsyncWriteStream io.Closer }
type AsyncWriteCallbackPacket ¶
type AsyncWriteCallbackPacket func(error)
type AsyncWriteStream ¶
type AsyncWriteStream interface { AsyncWriter AsyncCanceller io.Closer }
type AsyncWriter ¶
type AsyncWriter interface { // AsyncWrite writes up to `len(b)` bytes from `b` asynchronously. // // This call does not block. The provided completion handler is called in the following cases: // - a write of up to `n` bytes completes // - an error occurs // // Ownership of the byte slice must be retained by callers, which must guarantee that it remains valid until the // callback is invoked. This function does not modify the given byte slice, even temporarily. AsyncWrite(b []byte, cb AsyncCallback) // AsyncWriteAll writes exactly `len(b)` bytes into the underlying data stream asynchronously. AsyncWriteAll(b []byte, cb AsyncCallback) }
AsyncWriter is the interface that wraps the AsyncWrite and AsyncWriteAll methods.
type AsyncWriterTo ¶
type AsyncWriterTo interface {
AsyncWriteTo(AsyncWriter, AsyncCallback)
}
type BipBuffer ¶
type BipBuffer struct {
// contains filtered or unexported fields
}
BipBuffer is a circular buffer capable of providing continuous, arbitrarily sized byte chunks in a first-in-first-out manner.
A BipBuffer is useful when writing packet-based network protocols, as it allows one to access the packets in a first-in-first-out manner without allocations or copies. Callers are always provided a full packet and never have to care about wrapped byte chunks.
The usual workflow is as follows: - b = buf.Claim(128) - n = reader.Read(b) - buf.Commit(n) - b = buf.Claim(128) - n = reader.Read(b) - buf.Commit(n) - buf.Consume(128) gets rid of the first 128 bytes - buf.Consume(128) gets rid of the last 128 bytes
Copyright: Simon Cooke.
func NewBipBuffer ¶
func (*BipBuffer) Commit ¶
Commit n bytes of the previously claimed slice. Returns the committed chunk at the tail of the buffer.
func (*BipBuffer) Consume ¶
Consume n bytes from the head of the buffer. This means that the first n bytes will get overwritten by a Claim + Commit at some point.
func (*BipBuffer) Head ¶
Head returns the first (and possibly only) contiguous byte slice in the buffer.
func (*BipBuffer) Prefault ¶
func (buf *BipBuffer) Prefault()
Prefault the buffer, forcing physical memory allocation.
type ByteBuffer ¶
type ByteBuffer struct {
// contains filtered or unexported fields
}
ByteBuffer provides operations that make it easier to handle byte slices in networking code.
A ByteBuffer has 3 areas. In order: - save area: [0, si) - read area: [si, ri) - write area: [ri, wi)
A usual workflow is as follows:
- Bytes are written to the write area. These bytes cannot be read yet.
- Bytes from the write area are made available for reading in the read area, by calling Commit.
- Bytes from the read area can be either Saved or Consumed. If Saved, the bytes are kept in the save area. If Consumed, the bytes' lifetime ends, they are automatically discarded. Saved bytes must be discarded later.
Invariants: - 0 <= si <= ri <= wi <= min(len(data), cap(b.data)) <= cap(b.data) - everytime wi changes, b.data should grow/shrink accordingly:
- b.data = b.data[:b.wi]
func NewByteBuffer ¶
func NewByteBuffer() *ByteBuffer
func (*ByteBuffer) AsyncReadFrom ¶
func (b *ByteBuffer) AsyncReadFrom(r AsyncReader, cb AsyncCallback)
AsyncReadFrom the supplied asynchronous reader into the write area.
The buffer is not automatically grown to accommodate all data from the reader. The responsibility is left to the caller which can reserve enough space through Reserve.
func (*ByteBuffer) AsyncWriteTo ¶
func (b *ByteBuffer) AsyncWriteTo(w AsyncWriter, cb AsyncCallback)
AsyncWriteTo the provided asynchronous writer bytes from the read area. Consume them if no error occurred.
func (*ByteBuffer) Cap ¶
func (b *ByteBuffer) Cap() int
Cap returns the length of the underlying byte slice.
func (*ByteBuffer) Claim ¶
func (b *ByteBuffer) Claim(fn func(b []byte) int)
Claim a byte slice of the write area.
Claim allows callers to write directly into the write area of the buffer.
`fn` implementations should return the number of bytes written into the provided byte slice.
Callers have the option to write less than they claim. The amount is returned in the callback and the unused bytes will be used in future claims.
func (*ByteBuffer) ClaimFixed ¶
func (b *ByteBuffer) ClaimFixed(n int) (claimed []byte)
ClaimFixed claims a fixed byte slice from the write area.
Callers do not have the option to write less than they claim. The write area will grow by `n`.
func (*ByteBuffer) Commit ¶
func (b *ByteBuffer) Commit(n int)
Commit moves `n` bytes from the write area to the read area.
func (*ByteBuffer) Consume ¶
func (b *ByteBuffer) Consume(n int)
Consume removes the first `n` bytes of the read area. The removed bytes cannot be referenced after a call to Consume. If that's desired, use Save.
func (*ByteBuffer) Data ¶
func (b *ByteBuffer) Data() []byte
Data returns the bytes in the read area.
func (*ByteBuffer) Discard ¶
func (b *ByteBuffer) Discard(slot Slot) (discarded int)
Discard a previously saved slot.
This call reduces the save area by slot.Length. Returns slot.Length.
func (*ByteBuffer) DiscardAll ¶
func (b *ByteBuffer) DiscardAll()
DiscardAll saved slots.
The save area's size will be 0 after this call.
func (*ByteBuffer) Len ¶
func (b *ByteBuffer) Len() int
Len returns the length of the underlying byte slice.
func (*ByteBuffer) Prefault ¶
func (b *ByteBuffer) Prefault()
Prefault the buffer, forcing physical memory allocation.
NOTE: this should be used sparingly. Even though an array is contiguous in the process' virtual memory map, it is probably fragmented in main memory. Iterating over the array will cause a bunch of page faults, thus triggering virtual to physical memory mapping. This means that if you Reserve 1GB initially, you will get nothing allocated. But if you Prefault after Reserve, you will get the entire 1GB allocated which is maybe not what you want in a resourced constrained application.
func (*ByteBuffer) PrepareRead ¶
func (b *ByteBuffer) PrepareRead(n int) (err error)
PrepareRead prepares n bytes to be read from the read area. If less than n bytes are available, ErrNeedMore is returned and no bytes are committed to the read area, hence made available for reading.
func (*ByteBuffer) Read ¶
func (b *ByteBuffer) Read(dst []byte) (int, error)
Read the bytes from the read area into `dst`. Consume them.
func (*ByteBuffer) ReadByte ¶
func (b *ByteBuffer) ReadByte() (byte, error)
ReadByte returns and consumes one byte from the read area.
func (*ByteBuffer) ReadFrom ¶
func (b *ByteBuffer) ReadFrom(r io.Reader) (int64, error)
ReadFrom the supplied reader into the write area.
The buffer is not automatically grown to accommodate all data from the reader. The responsibility is left to the caller which can reserve enough space through Reserve.
func (*ByteBuffer) ReadLen ¶
func (b *ByteBuffer) ReadLen() int
ReadLen returns the length of the read area.
func (*ByteBuffer) Reserve ¶
func (b *ByteBuffer) Reserve(n int)
Reserve capacity for at least `n` more bytes to be written into the ByteBuffer's write area.
This call grows the write area by at least `n` bytes. This might allocate.
func (*ByteBuffer) Reserved ¶
func (b *ByteBuffer) Reserved() int
Reserved returns the number of bytes that can be written in the write area of the buffer.
func (*ByteBuffer) Reset ¶
func (b *ByteBuffer) Reset()
func (*ByteBuffer) Save ¶
func (b *ByteBuffer) Save(n int) (slot Slot)
Save n bytes from the read area. Save is like Consume, except that the bytes can still be referenced after the read area is updated.
Saved bytes should be discarded at some point with Discard(...).
func (*ByteBuffer) SaveLen ¶
func (b *ByteBuffer) SaveLen() int
SaveLen returns the length of the save area.
func (*ByteBuffer) ShrinkBy ¶
func (b *ByteBuffer) ShrinkBy(n int) int
ShrinkBy shrinks the write area by at most `n` bytes.
func (*ByteBuffer) ShrinkTo ¶
func (b *ByteBuffer) ShrinkTo(n int) (shrunkBy int)
ShrinkTo shrinks the write to contain min(n, WriteLen()) bytes.
func (*ByteBuffer) UnreadByte ¶
func (b *ByteBuffer) UnreadByte() error
UnreadByte from the write area.
func (*ByteBuffer) Write ¶
func (b *ByteBuffer) Write(bb []byte) (int, error)
Write the supplied slice into the write area. Grow the write area if needed.
func (*ByteBuffer) WriteByte ¶
func (b *ByteBuffer) WriteByte(bb byte) error
WriteByte into the write area. Grow the write area if needed.
func (*ByteBuffer) WriteLen ¶
func (b *ByteBuffer) WriteLen() int
WriteLen returns the length of the write area.
func (*ByteBuffer) WriteString ¶
func (b *ByteBuffer) WriteString(s string) (int, error)
WriteString into the write area. Grow the write area if needed.
type CodecConn ¶
type CodecConn[Enc, Dec any] struct { // contains filtered or unexported fields }
CodecConn reads/writes `Item`s through the provided `Codec`. For an example, see `codec/frame.go`.
func NewCodecConn ¶ added in v0.7.0
func (*CodecConn[Enc, Dec]) AsyncReadNext ¶
func (*CodecConn[Enc, Dec]) AsyncWriteNext ¶
func (c *CodecConn[Enc, Dec]) AsyncWriteNext(item Enc, cb AsyncCallback)
type Conn ¶
type Conn interface { FileDescriptor net.Conn }
Conn is a generic stream-oriented network connection.
type Decoder ¶
type Decoder[Item any] interface { // Decode the next `Item`, if any, from the provided buffer. If there are not enough bytes to decode an `Item`, // implementations should return an empty `Item` along with `ErrNeedMore`. `CodecConn` will then know to read more // bytes before calling `Decode(...)` again. Decode(src *ByteBuffer) (Item, error) }
type Encoder ¶
type Encoder[Item any] interface { // Encode the given `Item` into the given buffer. // // Implementations should: // - Commit() the bytes into the given buffer if the encoding is successful. // - Ensure the given buffer is big enough to hold the serialized `Item`s by calling `Reserve(...)`. Encode(item Item, dst *ByteBuffer) error }
type File ¶
type File interface { FileDescriptor io.Seeker }
type FileDescriptor ¶
type FileDescriptor interface { RawFd() int io.Closer io.ReadWriter AsyncReadWriter AsyncCanceller }
type IO ¶
type IO struct { // Tracks how many callbacks are on the current stack-frame. This prevents stack-overflows in cases where // asynchronous operations can be completed immediately. // // For example, an asynchronous read might be completed immediately. In that case, the callback is invoked which in // turn might call `AsyncRead` again. That asynchronous read might again be completed immediately and so on. In this // case, all subsequent read callbacks are placed on the same stack-frame. We count these callbacks with // `Dispatched`. If we hit `MaxCallbackDispatch`, then the stack-frame is popped - asynchronous reads are scheduled // to be completed on the next poll cycle, even if they can be completed immediately. // // This counter is shared amongst all asynchronous objects - they are responsible for updating it. Dispatched int // contains filtered or unexported fields }
IO is the executor of all asynchronous operations and the way any object can schedule them. It runs fully in the calling goroutine.
A goroutine must not have more than one IO. There might be multiple IOs in the same process, each within its own goroutine.
func (*IO) Deregister ¶
func (*IO) Poll ¶
Poll runs the event processing loop to execute ready handlers.
This will return immediately in case there is no event to process.
func (*IO) PollOne ¶
PollOne runs the event processing loop to execute one ready handler.
This will return immediately in case there is no event to process.
func (*IO) Post ¶
Post schedules the provided handler to be run immediately by the event processing loop in its own thread.
It is safe to call Post concurrently.
func (*IO) Posted ¶
Posted returns the number of handlers registered with Post.
It is safe to call Posted concurrently.
func (*IO) RunOne ¶
RunOne runs the event processing loop to execute at most one handler.
This call blocks the calling goroutine until an event occurs.
func (*IO) RunOneFor ¶
RunOneFor runs the event processing loop for the given duration. The duration must not be lower than 1ms.
This call blocks the calling goroutine until an event occurs.
func (*IO) RunPending ¶
RunPending runs the event processing loop to execute all the pending handlers. The function returns (and the event loop stops running) when there are no more operations to complete.
func (*IO) RunWarm ¶
RunWarm runs the event loop in a combined busy-wait and yielding mode, meaning that if the current cycle does not process anything, the event-loop will busy-wait for at most `busyCycles` which we call the warm-state. After `busyCycles` of not processing anything, the event-loop is out of the warm-state and falls back to yielding with the provided timeout. If at any moment an event occurs and something is processed, the event-loop transitions to its warm-state.
func (*IO) SetRead ¶
SetRead tells the kernel to notify us when reads can be made on the provided IO slot. If successful, this call must be succeeded by Register(slot).
It is safe to call this method multiple times.
func (*IO) UnsetRead ¶
UnsetRead tells the kernel to not notify us anymore when reads can be made on the provided IO slot. Since the underlying platform-specific poller already unsets a read before dispatching it, callers must only use this method they want to cancel a currently-scheduled read. For example, when an error occurs outside of an AsyncRead call and the underlying file descriptor must be closed. In that case, this call must be succeeded by Deregister(slot).
It is safe to call this method multiple times.
func (*IO) UnsetReadWrite ¶
UnsetRead and UnsetWrite in a single call.
type Listener ¶
type Listener interface { // Accept waits for and returns the next connection to the listener synchronously. Accept() (Conn, error) // AsyncAccept waits for and returns the next connection to the listener asynchronously. AsyncAccept(AcceptCallback) // Close closes the listener. Close() error // Addr returns the listener's network address. Addr() net.Addr RawFd() int }
Listener is a generic network listener for stream-oriented protocols.
func Listen ¶
Listen creates a Listener that listens for new connections on the local address.
If the option Nonblocking with value set to false is passed in, you should use Accept() to accept incoming connections. In this case, Accept() will block if no connections are present in the queue.
If the option Nonblocking with value set to true is passed in, you should use AsyncAccept() to accept incoming connections. In this case, AsyncAccept() will not block if no connections are present in the queue.
type PacketConn ¶
type PacketConn interface { ReadFrom([]byte) (n int, addr net.Addr, err error) AsyncReadFrom([]byte, AsyncReadCallbackPacket) AsyncReadAllFrom([]byte, AsyncReadCallbackPacket) WriteTo([]byte, net.Addr) error AsyncWriteTo([]byte, net.Addr, AsyncWriteCallbackPacket) Close() error Closed() bool LocalAddr() net.Addr RawFd() int }
PacketConn is a generic packet-oriented connection.
func ListenPacket ¶
func NewPacketConn ¶
NewPacketConn establishes a packet based stream-less connection which is optionally bound to the specified addr.
If addr is empty, the connection is bound to a random address which can be obtained by calling LocalAddr().
type Slot ¶
Slot from the save area. See Save and Discard.
func OffsetSlot ¶
OffsetSlot ...
Usually used when we reference a few Slots and Discard several of them. - Slots that precede a discarded Slot must be offset - Slots that follow a discarded Slot must not be offset
type SlotOffsetter ¶
type SlotOffsetter struct {
// contains filtered or unexported fields
}
SlotOffsetter helps with offsetting a Slot's Index such that the bytes referred by the slot can be safely removed from a ByteBuffer's saved area.
Why do we need to care about offsetting slots? Consider the following example, where [x, y] is a slot with Index x and Length n: - say we have the following slots, generated after calling ByteBuffer.Save(...): A:[0, 1] B:[1, 2] C:[3, 3] i.e. bytes: ABBCCC. - we ByteBuffer.Discard(B) and arrive at: ACCC - we want to ByteBuffer.Discard(C). However B was removed before C so [3, 3] now became [1, 3]. So C's index moved back by an offset of 2 bytes. - we offset C from [3, 3] to [1, 3] and then call ByteBuffer.Discard(C) which will give us A.
SlotOffsetter does the offsetting for you. The worflow is as follows: - slot := ByteBuffer.Save(...) - slot = offsetter.Add(slot) - ... - ByteBuffer.Discard(Offset(slot))
func NewSlotOffsetter ¶
func NewSlotOffsetter(maxBytes int) *SlotOffsetter
func (*SlotOffsetter) Add ¶
func (s *SlotOffsetter) Add(slot Slot) (Slot, error)
Add a slot such that it can be Offset accordingly at a later time. Slots are generated by calling ByteBuffer.Save().
func (*SlotOffsetter) Offset ¶
func (s *SlotOffsetter) Offset(slot Slot) Slot
Offset a previously Added slot such that it can be removed from the ByteBuffer's save area through ByteBuffer.Discard.
func (*SlotOffsetter) Reset ¶
func (s *SlotOffsetter) Reset()
type SlotSequencer ¶
type SlotSequencer struct {
// contains filtered or unexported fields
}
func NewSlotSequencer ¶
func NewSlotSequencer(maxSlots, maxBytes int) *SlotSequencer
func (*SlotSequencer) Bytes ¶
func (s *SlotSequencer) Bytes() int
func (*SlotSequencer) FillPct ¶
func (s *SlotSequencer) FillPct() float64
func (*SlotSequencer) MaxBytes ¶
func (s *SlotSequencer) MaxBytes() int
func (*SlotSequencer) Pop ¶
func (s *SlotSequencer) Pop(seq int) (Slot, bool)
Pop the slot identified by `seq`. The popped Slot must be discarded through ByteBuffer.Discard before Pop is called again.
func (*SlotSequencer) Push ¶
func (s *SlotSequencer) Push(seq int, slot Slot) (ok bool, err error)
Push a Slot that's uniquely identified and ordered by `seq`.
func (*SlotSequencer) Reset ¶
func (s *SlotSequencer) Reset()
func (*SlotSequencer) Size ¶
func (s *SlotSequencer) Size() int
type Socket ¶
type Socket struct {
// contains filtered or unexported fields
}
func NewSocket ¶
func NewSocket( domain SocketDomain, socketType SocketType, protocol SocketProtocol, ) (*Socket, error)
func (*Socket) BindToDevice ¶
BindToDevice binds the socket to the device with the given name. The device must be a network interface (`ip link` to see all interfaces).
This makes it such that only packets from the given device will be processed by the socket.
func (*Socket) BoundDevice ¶
func (*Socket) IsNonblocking ¶
func (*Socket) SetNoDelay ¶
func (*Socket) SetNonblocking ¶
func (*Socket) UnbindFromDevice ¶
UnbindFromDevice is not working, and honestly I have no clue why.
type SocketDomain ¶
type SocketDomain int
const ( SocketDomainUnix SocketDomain = iota SocketDomainIPv4 SocketDomainIPv6 )
func SocketDomainFromIP ¶
func SocketDomainFromIP(ip net.IP) SocketDomain
func (SocketDomain) String ¶
func (s SocketDomain) String() string
type SocketIOFlags ¶
type SocketIOFlags int
type SocketProtocol ¶
type SocketProtocol int
const ( SocketProtocolTCP SocketProtocol = iota SocketProtocolUDP )
func (SocketProtocol) String ¶
func (s SocketProtocol) String() string
type SocketType ¶
type SocketType int
const ( SocketTypeStream SocketType = iota SocketTypeDatagram SocketRaw )
func (SocketType) String ¶
func (s SocketType) String() string
type Stream ¶
type Stream interface { RawFd() int AsyncStream SyncStream }
Stream represents a full-duplex connection between two processes, where data represented as bytes may be received reliably in the same order they were written.
type SyncStream ¶
type SyncStream interface { SyncReadStream SyncWriteStream io.Closer }
type Timer ¶
type Timer struct {
// contains filtered or unexported fields
}
func (*Timer) Close ¶
Close closes the timer, render it useless for scheduling any more operations on it. A timer cannot be used after Close(). Any pending operations that have been scheduled but not yet completed are cancelled, and will therefore never complete.
func (*Timer) ScheduleOnce ¶
ScheduleOnce schedules a callback for execution after a delay.
The callback is guaranteed to never be called before the delay. However, it is possible that it will be called a little after the delay.
If the delay is negative or 0, the callback is executed as soon as possible.
func (*Timer) ScheduleRepeating ¶
ScheduleRepeating schedules a callback for execution once per interval.
The callback is guaranteed to never be called before the repeat delay. However, it is possible that it will be called a little after the repeat delay.
If the delay is negative or 0, the operation is cancelled.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package bytes provides containers and utilities for working with byte arrays and slices.
|
Package bytes provides containers and utilities for working with byte arrays and slices. |
codec
|
|
websocket
Based on https://datatracker.ietf.org/doc/html/rfc6455
|
Based on https://datatracker.ietf.org/doc/html/rfc6455 |
examples
|
|
net
|
|
stress_test
|
|
tests
|
|