powpow

This is a high-performance, event notification library for Nim. It provides a low-level event loop and timer wheel, as well as higher-level abstractions for building TCP/UDP, HTTP and WebSocket servers.

The library is designed to be minimal and efficient, with a focus on low-latency event handling and minimal overhead, providing a solid foundation for building high-performance networked applications in Nim.

Features

Core Event Loop (loop.nim)

  • Single-threaded non-blocking reactor
  • I/O multiplexing via kqueue (macOS/BSD), epoll (Linux), IOCP (Windows), poll (fallback), or the opt-in Linux io_uring backend (io/)
  • 4-level hierarchical timer wheel — O(1) insert/fire/cancel
  • One-shot and repeating interval timers
  • Deferred callbacks (executed before each I/O poll iteration)
  • Idle handlers (executed when no I/O events are pending)
  • Pointer-based fd watcher dispatch — zero hash-table lookups on the hot path
  • Generation-counter stale event detection
  • Dead watcher sweep with zombie/retired list for in-flight event safety
  • Thread-safe stop() via eventfd (Linux) or self-pipe (macOS/BSD)
  • Buffer pool for shared read buffers
  • Adaptive event capacity scaling (min 64, max 4096)

TCP Networking (net/tcp.nim)

  • Non-blocking TCP server with connection pooling
  • Non-blocking TCP client with async connect (DNS resolved on the loop)
  • Edge-triggered I/O events
  • Write buffering with automatic corking (TCP_CORK / TCP_NOPUSH)
  • Scatter-gather writes via writev
  • Zero-copy file send via sendfile (Linux sendfile, macOS sendfile, POSIX fallback)
  • Graceful shutdown with close-after-drain (closeAfterDrain)
  • Unix domain socket support (macOS/BSD/Linux)
  • SO_LINGER{0} for fast shutdown
  • Per-connection read buffer pooling

Async DNS (net/dns.nim)

  • In-loop DNS resolver (RFC 1035) — no blocking getaddrinfo, no worker threads
  • Reads /etc/hosts and /etc/resolv.conf (system resolver config)
  • A + AAAA queries with A-fallback; retries with timeout/attempts
  • TTL-based result cache + negative caching
  • resolveAddrAsync for users; connect uses it automatically
  • Numeric IP literals resolve inline (zero DNS I/O)

OS Signals (signal.nim)

  • In-process SignalRelay pub/sub bus (listen / listenOnce / unlisten)
  • watchOsSignal/watchOsSignals deliver real OS signals through the loop
  • OsSignal enum: SIGHUP, SIGINT, SIGQUIT, SIGUSR1/2, SIGPIPE, SIGALRM, SIGTERM, SIGURG, SIGCHLD, SIGIO
  • Platform-native delivery: signalfd (Linux), self-pipe (macOS/BSD/POSIX), SetConsoleCtrlHandler Ctrl+C (Windows) — no global signal handlers
  • Graceful shutdown on SIGINT/SIGTERM without blocking the loop

Stream I/O (stream.nim)

  • IoStream wraps an arbitrary non-blocking fd and drives it from the loop
  • Pipes, subprocess stdout, UDS and socketpair IPC; newStreamPair creates a full-duplex channel
  • Connection-style write path: direct write drained until EAGAIN, remainder buffered and flushed on Write events; 32 MiB queued-write cap
  • pause/resume read backpressure (a paused reader blocks the pipe writer)
  • close is the single terminal transition and fires onClose exactly once; closeAfterWrite flushes then delivers EOF to the peer
  • POSIX only (Windows IOCP is sockets-only); regular files work on kqueue but epoll rejects them

UDP Networking (net/udp.nim)

  • Non-blocking UDP server (bind) and client (connect)
  • recvfrom / sendto for connectionless communication
  • Connected UDP sockets for peer-scoped send/recv

HTTP/1.1 Parser (proto/http.nim)

  • Incremental, zero-copy parser — materialize strings lazily from byte offsets
  • O(1) method dispatch via first-byte switch
  • Pipelined request support
  • Streaming body handling via callback
  • Chunked transfer encoding
  • Body streaming to file
  • Multipart form data support

HTTP Server (proto/httpserver.nim)

  • Implement your-own-router — lower-level callback-based design
  • OnRequestCallback* = proc(req: HttpRequest, res: HttpResponse) {.gcsafe.}
  • Higher-level frameworks implement routing on top of this callback
  • Streaming response body
  • Static file serving with MIME type detection
  • Conditional requests (If-Modified-Since, If-None-Match)
  • Range requests with 206 Partial Content
  • Directory listing
  • CORS headers
  • Streaming multipart upload handling
  • Pipelined request-response processing

WebSocket (proto/ws.nim)

  • RFC 6455 compliant
  • Standalone WebSocket server mode
  • HTTP upgrade from HttpServer routes
  • Text, binary, ping/pong, and close frames
  • Per-message deflate extension
  • Masked frame handling

Multi-threaded HTTP Server (proto/multithread.nim)

  • SO_REUSEPORT kernel-level connection distribution
  • One event loop + listen socket per worker thread
  • Zero cross-thread communication — no single-threaded acceptor bottleneck
  • Graceful shutdown via shutdown pipe

SIMD-Accelerated Scanning (proto/simdscan.nim)

  • SSE2-accelerated CRLF detection
  • Scalar fallback for non-x86 architectures

Platform Abstraction (platform/)

  • kqueue — macOS/BSD (high-performance, edge-triggered)
  • epoll — Linux (with eventfd wake)
  • iocp — Windows (I/O Completion Ports)
  • poll — POSIX fallback
  • io/ — Linux io_uring backend (submission-based, opt-in). Enabled with nimble --features:io_uring <cmd>, requires "powpow[io_uring]", or nim c -d:powpowIoUring. The same public API, driven by IORING_OP_ACCEPT/RECV/SEND/CONNECT/SEND_ZC/SPLICE/... completions instead of readiness events; the generic fd-watcher API is emulated with one-shot IORING_OP_POLL_ADD. Ships the full io_uring API binding (io/uring.nim), IORING_REGISTER_PROBE feature detection, zero-copy SEND_ZC and SPLICE file sends, and registered buffers (IORING_REGISTER_BUFFERS). Requires Linux >= 5.6.

Networking Common (net/common.nim)

  • Platform-agnostic socket API and address resolution (IPv4 + IPv6)
  • Socket options: non-blocking, SO_REUSEADDR, SO_REUSEPORT, TCP_NODELAY
  • sendfile zero-copy file transmission
  • Cross-platform error handling (EAGAIN, EINPROGRESS, etc.)
  • Auto-initialization (WSAStartup on Windows, SIGPIPE ignore on POSIX)

Exports

==, TimerCallback, HttpConnect, HttpPatch, HttpGet, HttpHead, EventType, FdCallback, TimerId, HttpPost, HttpTrace, HttpMethod, HttpPut, HttpOptions, TlsState, HttpDelete, ObserverCallback, Callback, iouEnabled, modify, ensureCapacity, HttpConnect, HttpPatch, ==, HttpGet, HttpHead, HttpPost, HttpMethod, FdCallback, remove, add, TimerCallback, EventType, HttpPut, PlatformEvent, HttpOptions, TlsState, TimerId, HttpDelete, HttpTrace, Platform, init, poll, ObserverCallback, Callback, wake, iouEnabled, addIdle, HttpConnect, pollWallSec, removeIdle, HttpGet, timerCount, releaseBuf, HttpPost, EventType, addCleanup, close, remove, pollNowMs, add, unregisterFd, HttpTrace, ==, deferCall, observe, addTimer, PlatformEvent, HttpOptions, TlsState, ensureCapacity, init, modify, FdWatcher, addInterval, runOnce, close, poll, wake, iouEnabled, Observer, unregister, TimerId, HttpPatch, monoMs, modify, acquireBuf, HttpHead, run, register, postToLoop, newLoop, HttpDelete, FdCallback, TimerCallback, poll, HttpMethod, HttpPut, resumeTimer, addTurnEndHook, pauseTimer, Loop, Platform, isRunning, cancelTimer, ObserverCallback, Callback, cancelObserver, stop, addIdle, sockInProgress, DtlsMaxChunk, HttpGet, FdCallback, addInterval, close, timerCount, bindUdp, HttpPost, observe, sendv, monoMs, HttpPut, SEEK_END, TxtCallback, DnsResolver, shutdown, remove, setTcpNoDelay, MaxConnPoolSize, sockWritev, OnUdpData, closeFile, close, close, setAlpnProtocols, sockaddrFromIp, HttpTrace, addTimer, maxBufPoolSize, sendFile, DtlsConfig, HttpOptions, HttpDelete, TlsState, IoStream, Platform, write, readFile, sockRecv, driveHandshake, connectUdp, sendTo, lastSocketError, O_BINARY, O_RDONLY, closeDns, unregisterFd, DtlsMtuDefault, sessionCount, close, wrapTls, OnAccept, Observer, closeAfterSend, DnsCacheEntry, send, ConnState, listenUnix, send, unregister, TimerId, IoStreamState, addCleanup, sockWouldBlock, newClientTlsContext, HttpHead, connectUnix, injectFd, close, removeIdle, close, setReuseAddr, sendTo, SslError, newServerTlsContext, tlsRead, run, getClientSockAddr, newTcpServer, postToLoop, isTlsActive, flushWriteBuffer, MxCallback, TimerCallback, sendFileActive, FdWatcher, acquireBuf, MaxIoStreamWriteBuffer, cancelObserver, newDtlsServer, resumeTimer, closeAfterDrain, addTurnEndHook, closeAndRelease, sockShutdown, cancelSendFile, DtlsSweepIntervalDefaultMs, ==, tlsFree, DefaultSendFileChunk, SEEK_CUR, sendTo, maxWriteBufferSize, newServerDtlsContext, Callback, DtlsError, OnError, SendFileChunkSize, newStreamPair, resume, releaseBuf, OnData, openStream, listen, openFileRead, connectDtls, HttpConnect, pollWallSec, DtlsSession, sockSend, resolveAddr, EventType, getSockLen, continueSendFile, DtlsMaxSessionsDefault, connectHe, close, setReusePort, pollNowMs, close, UNIX_PATH_MAX, MaxBufPoolSize, TxtRecord, write, DtlsRole, DtlsSessionState, deferCall, send, newConnection, setTcpCork, resolveMxAsync, ensureCapacity, setNonBlocking, finCloseNow, OnClose, init, SslContext, alpnSelected, initNet, runOnce, isIpAddress, UdpSocket, sendFileChunk, Connection, Loop, configureDns, peerAddrStr, wake, sockInterrupted, resolveTxtAsync, iouEnabled, add, send, DnsCallback, connect, sendTo, DtlsContext, register, setDnsServers, modify, seekFile, HttpPatch, setIpv6Only, pause, newLoop, DtlsServer, maxConnPoolSize, poll, resolveAddrBothAsync, closeAfterWrite, tlsWrite, ResolvedIp, getClientIp, poll, formatIp, defaultDtlsConfig, ObserverCallback, resolveAddrAsync, getFileSize, sendTo, TlsRole, HttpMethod, resolveAddrAll, TcpServer, SEEK_SET, DefaultBufSize, MxRecord, pauseTimer, DnsQuery, send, newClientDtlsContext, NetError, DtlsHandshakeTimeoutDefaultMs, modify, DtlsIdleTimeoutDefaultMs, sockClose, isRunning, send, PlatformEvent, cancelTimer, stop, H2ConnectionPreface, shutdown, withinRoot, isComplete, HttpRequest, onMessage, TcpServer, reset, WsErrorCb, writeFrameMasked, options, huffmanEncodeInto, h2Draining, sendPong, close, decode, releaseBuf, stageFrame, encodeFrameInto, removeSession, header, drainChunk, getConn, post, post, start, addIdle, onData, peekMethod, sendMessage, WsCloseCb, encodeWindowUpdate, modify, H2ClientConn, encodeIntInto, listen, setError, newWsServer, H2Role, head, start, H2DefaultMaxConcurrent, HttpConnect, status, unregisterFd, pollWallSec, DefaultChunkSize, reset, removeIdle, HttpOptions, sendError, HttpGet, options, getTrailers, idleConnections, close, timerCount, headersDone, getBodyStream, stageFrame, HttpError, close, HttpPost, HttpMethod, H2FrameHeaderLen, connectH2Tls, sendHandshakeRequest, continueSendFile, sendv, header, peekContentType, listenUnix, push, connectHe, decodeInt, request, getStatusText, newProxyServer, isRunning, start, WsConnection, getClientIp, initHuffman, OnH2RequestCallback, remove, post, start, sendMessage, DefaultIdleTimeoutMs, newMultiRateLimiter, ProxyDir, start, OnData, newH2ClientPool, OnProxyData, getBodyView, MaxConnPoolSize, H2MaxFrameSizeMin, pollNowMs, encodeStringInto, MaxRequestLine, closeWs, addCleanup, setMaxPending, startClientPreface, DefaultMaxIdlePerHost, close, getMultipart, put, close, getConnectionClose, feed, OnProxyClose, appendBytes, put, resetForNext, MaxWsPoolSize, MaxBufPoolSize, stop, getLoop, H2SendBufCap, idleConnectionsFor, error, pendingBytes, isOk, H2Conn, phase, close, decodePing, listen, request, encodeSettings, H2ClientPool, add, onUpstreamData, send, get, emptyH2Body, observe, encodeData, addTimer, setKeepAliveTimeout, flushStagedH2, listen, connectUnix, setMaxTableSize, maxBufPoolSize, sendFile, newConnection, request, getBody, request, OnRequestCallback, patch, OnError, PlatformEvent, newLoop, H2Server, HttpDelete, TlsState, getLoop, MaxHeaders, WindowLimit, getTrailer, markSent, newProxyServer, ensureCapacity, streamFile, getContentLength, isChunked, head, patch, listen, finCloseNow, hasTrailers, Platform, onClose, init, H2DefaultWindowSize, run, listen, modify, start, driveHandshake, OnProxyUpstreamConnect, PoolKey, FdWatcher, H2FlagEndStream, status, sendBinary, getRemainingData, getBodyString, post, H2FrameType, runOnce, H2FlagPadded, decodeString, readChunk, tlsRead, ensureTcpServer, head, openClientStream, decodeGoaway, tryAdvance, onConnect, start, encode, poll, setUpstreamUnix, connectH2, encodeInto, getLoop, onClose, decodeSettings, H2Frame, encodeFrame, close, check, request, encodePing, wake, getBody, newHttpServer, OnAccept, getStatusCode, iouEnabled, wsPoolPop, parseRange, Observer, HpackDefaultTableSize, closeAfterSend, H2Request, setUpstream, serveStatic, getStatusCode, newAsyncHttpClient, peekPath, send, DefaultMaxFrameSize, flushSendBuf, newHttpClient, send, get, MaxHeaderSize, HttpResponse, readChunkInto, newH2Server, ParsePhase, H2ClientResponse, isBytesUnit, parseWsFrames, ConnState, WsMessageCb, connect, websocketUpgrade, H2Response, MultiThreadHttpServer, HttpClientResponse, PooledConn, H2DefaultMaxHeaderList, patchFrameHeader, encodeHeaders, pauseTimer, send, RateLimiter, unregister, ProxyServer, TimerId, put, get, close, listen, getTrailer, sendPing, request, options, populatePools, writeFrame, getPath, stop, removeFromPool, headerBytes, delete, getRequest, H2ErrorCode, addConnection, HpackError, getHeaders, HttpPatch, options, H2FlagEndHeaders, monoMs, ==, getMethod, acquireBuf, listen, HttpHead, getTrailers, newWsServer, ConnHttp, wsPoolAdd, H2ClientCallback, writeDisposition, computeAcceptKey, idleConnections, close, streamToFile, h2Closed, newRateLimiter, sendFile, DefaultBodyBuf, start, maxConnPoolSize, close, hasTrailers, resolveReal, onUpstreamConnect, start, getFileExt, getHeaders, peekChunk, peekAll, HpackMaxStringLen, HttpServer, close, H2StreamState, run, isError, reset, H2FlagPriority, FdCallback, H2FrameParser, MaxStreamBodySize, encodePingAck, isEstablished, newHttpConnPool, tcpServer=, getBody, ProxyPair, encodeGoaway, encodeString, delete, DefaultKeepAliveMs, HpackHeader, encodeSettingsAck, newTcpServer, Connection, newH2Conn, onOpen, postToLoop, close, getClientSockAddr, allow, tlsWrite, getHttpMinor, getClientIp, flushWriteBuffer, sendText, sendHandshake, getBodyString, newHttpParser, WsError, MultiThreadH2Server, H2Setting, injectFd, huffmanDecode, getConnectionClose, getQuery, upgradeToWs, newHttpServer, closeAll, H2MaxWindowSize, request, formatIp, getConnectionClose, connectWs, decodeRstStream, TimerCallback, H2Error, newWsConnection, ObserverCallback, HttpClientBase, sendFileActive, close, getClientIp, WsServer, H2MaxFrameSizeMax, serveFile, H2FlagAck, H2SettingsId, start, feedH2, stop, HpackContext, WsFrameKind, close, readChunkString, DefaultMaxPending, teardownByUpstreamFd, frameTypeFromInt, register, getUrl, poll, getContentLength, OnProxyError, EventType, tcpServer, listenUnix, head, encodeInt, HttpPut, H2DefaultMaxBody, resumeTimer, listenUnix, HttpParser, closeAfterDrain, addTurnEndHook, buildHandshakeResponse, decodeWindowUpdate, closeAndRelease, HttpTrace, put, patch, HpackStaticTableLen, get, listen, send, getHeaderValue, request, getProtocol, parseWsUrl, getStatusText, getContentLength, patch, deferCall, cancelSendFile, Loop, addInterval, DefaultMaxIdleTotal, WsOpenCb, DefaultMaxResponseBody, HttpClient, OnClose, onError, finalizeCloseDelimited, setMaxConnections, decodePriority, ensureH2FlushHook, newH2FrameParser, newProxyServer, tlsFree, listen, OnProxyConnect, delete, getHeaderValue, start, newMultiThreadH2Server, start, getHeaders, close, cancelTimer, MinStreamBodySize, delete, maxWriteBufferSize, huffmanEncode, handshakeCount, close, HttpBodyCallback, encodeRstStream, BodyStream, onClientData, reserveFrameHeader, encodePriority, newHttpServer, H2Stream, Callback, feed, cancelObserver, pop, H2ClientMaxStreamsHint, AsyncHttpClient, hpackError, newHpackContext, bodyView, onError, send, HttpConnPool, H2DefaultMaxFrameSize, feed, emit, ListenerHandle, watchOsSignals, watchOsSignal, listen, signalNumber, newOsSignalRelay, listen, OsSignal, SIG_BLOCK, unlisten, newSignalRelay, listenOnce, listenOnce, close, FileSystemEvent, FileWatcherCb, newFileWatcher, FileWatcher, HeartbeatMs, HttpConnect, HttpPatch, ==, HttpGet, HttpHead, ThreadPoolError, HttpPost, HttpMethod, shutdownThreadPool, newThreadPool, FdCallback, getLoop, TimerCallback, closeThreadPool, EventType, HttpPut, HttpOptions, TlsState, TimerId, HttpDelete, HttpTrace, submitWork, ObserverCallback, Callback, iouEnabled, ThreadPool, DefaultMaxFrameSize, onMessage, releaseBuf, newWsConnection, ==, parseWsFrames, WsMessageCb, addIdle, newWsClient, WsCloseCb, setAlpnProtocols, writeFrameMasked, WsRetryCb, unregister, HttpGet, onMessage, run, writeFrame, HttpConnect, alpnSelected, connect, pollWallSec, HttpPatch, newWsServer, monoMs, addCleanup, WsErrorCb, isRunning, acquireBuf, listen, HttpHead, onOpen, newWsServer, cancelObserver, sendPong, sendMessage, timerCount, poll, WsServer, TlsState, close, HttpPost, HttpMethod, sendHandshakeRequest, SslError, sendText, HttpDelete, cancelTimer, reset, FdCallback, WsConnection, websocketUpgrade, onGiveUp, close, remove, WsError, session, register, postToLoop, connect, removeIdle, isTlsActive, wrapTls, newLoop, sendMessage, sendBinary, getProtocol, pollNowMs, closeWs, TimerId, newServerTlsContext, upgradeToWs, computeAcceptKey, connectWs, DefaultWsReconnectPolicy, sendMessage, deferCall, add, newClientTlsContext, observe, WsFrameKind, addTimer, onRetry, unregisterFd, close, EventType, HttpPut, TimerCallback, resumeTimer, PlatformEvent, HttpOptions, HttpTrace, isConnected, addTurnEndHook, ensureCapacity, parseWsUrl, sendPing, pauseTimer, Platform, addInterval, modify, handshakeCount, onClose, FdWatcher, init, WsClient, SslContext, run, runOnce, buildHandshakeResponse, WsGiveUpCb, attemptCount, modify, onOpen, WsOpenCb, sendMessage, sendHandshake, start, setTlsContext, poll, isEstablished, TlsRole, onClose, onError, ObserverCallback, close, Callback, Loop, wake, onError, iouEnabled, WsReconnectPolicy, Observer, stop