### Run Netpoll Server Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Demonstrates how to start the Netpoll server by binding the EventLoop to a Listener. The Serve function blocks until an error occurs. ```go package main import ( "github.com/cloudwego/netpoll" ) var eventLoop netpoll.EventLoop func main() { ... // start listen loop ... eventLoop.Serve(listener) } ``` -------------------------------- ### Standard Library net.Conn Read/Write Example Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Illustrates traditional data handling with net.Conn, involving manual buffer copying for reading and writing multiple data sets. This approach requires explicit data packing and unpacking. ```go package main import ( "net" ) func main() { var conn net.Conn var buf = make([]byte, 8192) // reading for { n, _ := conn.Read(buf) ... unpacking & handling ... var i int for i = 0; i <= n-pkgsize; i += pkgsize { pkg := append([]byte{}, buf[i:i+pkgsize]...) go func() { ... handling pkg ... } } buf = append(buf[:0], buf[i:n]...) } // writing var write_datas <-chan []byte ... packing write ... for { pkg := <-write_datas conn.Write(pkg) } } ``` -------------------------------- ### Create and Convert Netpoll Listeners Source: https://context7.com/cloudwego/netpoll/llms.txt Create native Netpoll listeners or wrap existing net.Listener instances. Useful for native sockets or integrating with TLS/testing setups. ```go package main import ( "log" "net" "github.com/cloudwego/netpoll" ) func main() { // Option A: native netpoll listener ln, err := netpoll.CreateListener("tcp", ":9090") if err != nil { log.Fatal(err) } // Option B: convert an existing net.Listener (e.g. after TLS wrapping) rawLn, _ := net.Listen("tcp", ":9091") npLn, err := netpoll.ConvertListener(rawLn) if err != nil { log.Fatal(err) } _ = npLn eventLoop, _ := netpoll.NewEventLoop(onRequest) eventLoop.Serve(ln) } func onRequest(ctx interface{ Value(key interface{}) interface{} }, conn netpoll.Connection) error { return nil } ``` -------------------------------- ### Netpoll nocopy Read/Write Example Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Demonstrates Netpoll's nocopy APIs for reading and writing data without explicit copying, utilizing reference counting for resource management. Use Reader.Slice for reading and Writer.Append for writing. ```go package main import ( "github.com/cloudwego/netpoll" ) func main() { var conn netpoll.Connection // reading eader := conn.Reader() for { ... unpacking & handling ... pkg, _ := reader.Slice(pkgsize) go func() { ... handling pkg ... pkg.Release() } } // writing var write_datas <-chan netpoll.Writer ... packing write ... writer := conn.Writer() for { select { case pkg := <-write_datas: writer.Append(pkg) default: if writer.MallocLen() > 0 { writer.Flush() } } } } ``` -------------------------------- ### Create Net Listener Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Demonstrates how to create a standard net.Listener for server operations. ```go package main import "net" func main() { listener, err := net.Listen(network, address) if err != nil { panic("create net listener failed") } ... } ``` -------------------------------- ### Server-side Connection Preparation with OnPrepare Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Registers an OnPrepare function to execute when a new connection is accepted on the server. This function can prepare the connection and return a context for subsequent business processing. ```go package main import ( "context" "github.com/cloudwego/netpoll" ) func main() { // register OnPrepare var onPrepare netpoll.OnPrepare = prepare ev l, _ := netpoll.NewEventLoop(handler, netpoll.WithOnPrepare(onPrepare)) ... } func prepare(connection netpoll.Connection) (ctx context.Context) { ... prepare connection ... return } ``` -------------------------------- ### Create Netpoll Listener Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Shows how to create a Netpoll-specific Listener, which is compatible with server usage. ```go package main import "github.com/cloudwego/netpoll" func main() { listener, err := netpoll.CreateListener(network, address) if err != nil { panic("create netpoll listener failed") } ... ``` -------------------------------- ### Create Netpoll Dialer Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Demonstrates creating a Netpoll Dialer to establish client connections. This is an alternative to the 'fast way' public functions. ```go package main import ( "github.com/cloudwego/netpoll" ) func main() { // Dial a connection with Dialer. dialer := netpoll.NewDialer() conn, err := dialer.DialConnection(network, address, timeout) if err != nil { panic("dial netpoll connection failed") } ... ``` -------------------------------- ### Client-side Connection Preparation Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Prepares a new connection directly on the client side after establishing it via Dialer. This allows for user-controlled preparation logic before using the connection. ```go package main import ( "context" "github.com/cloudwego/netpoll" ) func main() { conn, err := netpoll.DialConnection(network, address, timeout) if err != nil { panic("dial netpoll connection failed") } ... prepare here directly ... prepare(conn) ... } func prepare(connection netpoll.Connection) (ctx context.Context) { ... prepare connection ... return } ``` -------------------------------- ### Pre-initialize Pollers with netpoll.Initialize Source: https://context7.com/cloudwego/netpoll/llms.txt Call Initialize in init() to pre-warm the internal epoll/kqueue pollers. This avoids the latency cost on the first connection burst, improving performance for initial connection loads. ```go func init() { // Pre-initialize pollers so the first connection doesn't pay startup cost netpoll.Initialize() } ``` -------------------------------- ### Create NIO Server with netpoll.NewEventLoop Source: https://context7.com/cloudwego/netpoll/llms.txt Constructs an event-driven server using NewEventLoop. Configure callbacks like OnRequest, OnPrepare, OnConnect, and OnDisconnect, along with timeouts. The Serve method blocks until an error or Shutdown occurs. ```go package main import ( "context" "log" "net" "time" "github.com/cloudwego/netpoll" ) func main() { listener, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } eventLoop, err := netpoll.NewEventLoop( onRequest, netpoll.WithOnPrepare(onPrepare), netpoll.WithOnConnect(onConnect), netpoll.WithOnDisconnect(onDisconnect), netpoll.WithReadTimeout(10*time.Second), netpoll.WithIdleTimeout(2*time.Minute), ) if err != nil { log.Fatal(err) } log.Println("Server listening on :8080") // Serve blocks until error or Shutdown if err := eventLoop.Serve(listener); err != nil { log.Println("Server stopped:", err) } } func onPrepare(conn netpoll.Connection) context.Context { // Called immediately after accept, before any data arrives. // Ideal for rate-limiting or attaching request-scoped metadata. return context.WithValue(context.Background(), "connectedAt", time.Now()) } func onConnect(ctx context.Context, conn netpoll.Connection) context.Context { log.Printf("New connection from %s", conn.RemoteAddr()) return ctx } func onDisconnect(ctx context.Context, conn netpoll.Connection) { log.Printf("Connection closed: %s", conn.RemoteAddr()) } func onRequest(ctx context.Context, conn netpoll.Connection) error { reader := conn.Reader() // Read a 4-byte length prefix header, err := reader.Next(4) if err != nil { return err } msgLen := int(header[0])<<24 | int(header[1])<<16 | int(header[2])<<8 | int(header[3]) body, err := reader.Next(msgLen) if err != nil { return err } response := append([]byte(nil), body...) // copy before Release reader.Release() // must release after done with nocopy slices // Echo the body back with the same length prefix writer := conn.Writer() buf, _ := writer.Malloc(4 + len(response)) buf[0], buf[1], buf[2], buf[3] = byte(len(response)>>24), byte(len(response)>>16), byte(len(response)>>8), byte(len(response)) copy(buf[4:], response) return writer.Flush() } ``` -------------------------------- ### Global Netpoll Runtime Configuration Source: https://context7.com/cloudwego/netpoll/llms.txt Configure Netpoll's internal behaviors using netpoll.Configure. Must be called in an init() function before connections are created. ```go package main import ( "context" "io/ioutil" "runtime" "github.com/cloudwego/netpoll" "github.com/bytedance/gopkg/util/gopool" ) func init() { pool := gopool.NewPool("netpoll-handler", 10000, gopool.NewConfig()) err := netpoll.Configure(netpoll.Config{ // One poller per 20 CPU cores (recommended ratio) PollerNum: runtime.GOMAXPROCS(0)/20 + 1, // 16KB initial buffer per connection (default 8KB) BufferSize: 16 * 1024, // Use a custom goroutine pool for OnRequest callbacks Runner: func(ctx context.Context, f func()) { pool.CtxGo(ctx, f) }, // Silence internal logs in production LoggerOutput: ioutil.Discard, // Distribute connections round-robin across pollers LoadBalance: netpoll.RoundRobin, }) if err != nil { panic(err) } } ``` -------------------------------- ### netpoll.Configure Source: https://context7.com/cloudwego/netpoll/llms.txt Provides a unified way to configure Netpoll's global runtime behaviors. Must be called before any connections are created. ```APIDOC ## netpoll.Configure ### Description `Configure` is the primary method for tuning all internal Netpoll behaviors globally. It must be called from an `init()` function before any connection is created, as pollers read these settings at startup. ### Method `Configure(config netpoll.Config)` ### Parameters - `config` (netpoll.Config) - Required - A struct containing various configuration options: - `PollerNum` (int) - Number of pollers to use. - `BufferSize` (int) - Initial buffer size per connection. - `Runner` (func(context.Context, func())) - Custom goroutine pool for callbacks. - `LoggerOutput` (io.Writer) - Output for internal logs. - `LoadBalance` (netpoll.LoadBalanceType) - Load balancing strategy for connections. ### Request Example ```go err := netpoll.Configure(netpoll.Config{ PollerNum: runtime.GOMAXPROCS(0)/20 + 1, BufferSize: 16 * 1024, Runner: func(ctx context.Context, f func()) { pool.CtxGo(ctx, f) }, LoggerOutput: ioutil.Discard, LoadBalance: netpoll.RoundRobin, }) if err != nil { panic(err) } ``` ### Response - `error` - Returns an error if the configuration fails. ``` -------------------------------- ### Nocopy Write Interface with Connection.Writer Source: https://context7.com/cloudwego/netpoll/llms.txt Employ `Connection.Writer()` for zero-copy writes to the connection's output buffer. Use `Malloc` to reserve space, fill the returned slice, and then `Flush`. `WriteString`, `WriteBinary`, and `WriteByte` are convenient helpers. `Append` can merge other writers. ```go func writeProtocolFrame(conn netpoll.Connection, msgType uint8, payload []byte) error { writer := conn.Writer() // Option 1: Malloc + fill header, err := writer.Malloc(5) // 1 byte type + 4 bytes length if err != nil { return err } header[0] = msgType binary.BigEndian.PutUint32(header[1:5], uint32(len(payload))) // Option 2: WriteBinary — references payload in-place, no copy (don't mutate payload before Flush) if _, err := writer.WriteBinary(payload); err != nil { return err } // Option 3: append a pre-built Writer (e.g. from another buffer) // writer.Append(otherWriter) return writer.Flush() } // Batch multiple writes before a single Flush for efficiency func batchWrite(conn netpoll.Connection, messages []string) error { writer := conn.Writer() for _, msg := range messages { if _, err := writer.WriteString(msg + "\n"); err != nil { return err } } return writer.Flush() // single syscall for all messages } ``` -------------------------------- ### Connection.Writer Source: https://context7.com/cloudwego/netpoll/llms.txt `Connection.Writer()` returns a `Writer` backed by the connection's output `LinkBuffer`. The two-step pattern is: `Malloc` to reserve space, fill the slice, then `Flush` to submit. `WriteString`, `WriteBinary`, and `WriteByte` are shorthand helpers. `Append` merges another `Writer` zero-copy. ```APIDOC ## Connection.Writer — Nocopy Write Interface ### Description `Connection.Writer()` returns a `Writer` backed by the connection's output `LinkBuffer`. The two-step pattern is: `Malloc` to reserve space, fill the slice, then `Flush` to submit. `WriteString`, `WriteBinary`, and `WriteByte` are shorthand helpers. `Append` merges another `Writer` zero-copy. ### Method `conn.Writer() netpoll.Writer ### Usage ```go writer := conn.Writer() // Option 1: Malloc + fill header, err := writer.Malloc(5) header[0] = msgType // Option 2: WriteBinary (no copy) _, err := writer.WriteBinary(payload) // Option 3: Append another Writer // writer.Append(otherWriter) // Submit buffered data err := writer.Flush() ``` ``` -------------------------------- ### Create Netpoll EventLoop Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Illustrates the creation of a Netpoll EventLoop, a NIO server component, with custom options like OnPrepare and ReadTimeout. ```go package main import ( "time" "github.com/cloudwego/netpoll" ) var eventLoop netpoll.EventLoop func main() { ... eventLoop, _ := netpoll.NewEventLoop( handle, netpoll.WithOnPrepare(prepare), netpoll.WithReadTimeout(time.Second), ) ... ``` -------------------------------- ### Nocopy Read Interface with Connection.Reader Source: https://context7.com/cloudwego/netpoll/llms.txt Utilize `Connection.Reader()` for zero-copy reads directly from the connection's buffer. Methods like `Peek`, `Skip`, and `Until` operate on the buffer without copying. Remember to call `Release` when done with the data. ```go func onRequest(ctx context.Context, conn netpoll.Connection) error { reader := conn.Reader() // Peek without advancing — useful for inspecting a protocol magic number magic, err := reader.Peek(2) if err != nil { return err } if magic[0] != 0xCA || magic[1] != 0xFE { conn.Close() return nil } // Skip the 2-byte magic reader.Skip(2) // Read a newline-delimited command (nocopy view into buffer) line, err := reader.Until('\n') if err != nil { return err } command := string(line) // copy to string before Release // Slice out a sub-reader for a fixed-size payload — zero-copy payloadSize := 256 subReader, err := reader.Slice(payloadSize) if err != nil { return err } go func() { defer subReader.Release() payload, _ := subReader.Next(payloadSize) processPayload(command, payload) }() reader.Release() return nil } func processPayload(cmd string, data []byte) { // handle asynchronously } ``` -------------------------------- ### Adapt Netpoll Reader/Writer to io.Reader/Writer with netpoll.NewIOReader/NewIOWriter Source: https://context7.com/cloudwego/netpoll/llms.txt These adapter functions bridge Netpoll's nocopy interfaces with Go's standard io.Reader and io.Writer. This enables interoperability with libraries that expect standard interfaces, such as the compress/gzip package. ```go package main import ( "compress/gzip" "io" "github.com/cloudwego/netpoll" ) func decompressFromConnection(conn netpoll.Connection) ([]byte, error) { // Wrap netpoll.Reader as io.Reader for gzip ioReader := netpoll.NewIOReader(conn.Reader()) gr, err := gzip.NewReader(ioReader) if err != nil { return nil, err } defer gr.Close() data, err := io.ReadAll(gr) conn.Reader().Release() return data, err } func compressToConnection(conn netpoll.Connection, data []byte) error { // Wrap netpoll.Writer as io.Writer for gzip ioWriter := netpoll.NewIOWriter(conn.Writer()) gw := gzip.NewWriter(ioWriter) if _, err := gw.Write(data); err != nil { return err } gw.Close() return conn.Writer().Flush() } ``` -------------------------------- ### Set Go Runtime GOMAXPROCS Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Configure the maximum number of operating system threads that can execute Go code simultaneously by setting the GOMAXPROCS environment variable or using runtime.GOMAXPROCS. ```go package main import ( "runtime" ) func init() { runtime.GOMAXPROCS(num_you_want) } ``` -------------------------------- ### netpoll.Initialize Source: https://context7.com/cloudwego/netpoll/llms.txt Pre-warms the internal epoll/kqueue pollers instead of waiting for the first connection. Calling it in init() reduces latency on the first connection burst. ```APIDOC ## netpoll.Initialize — Eager Poller Startup `Initialize` pre-warms the internal epoll/kqueue pollers instead of waiting for the first connection. Calling it in `init()` reduces latency on the first connection burst. ### Usage Example ```go func init() { // Pre-initialize pollers so the first connection doesn't pay startup cost netpoll.Initialize() } ``` ``` -------------------------------- ### netpoll.CreateListener / netpoll.ConvertListener Source: https://context7.com/cloudwego/netpoll/llms.txt Utilities for creating Netpoll-compatible listeners. `CreateListener` makes a new listener, while `ConvertListener` wraps an existing `net.Listener`. ```APIDOC ## netpoll.CreateListener / netpoll.ConvertListener ### Description These functions provide ways to obtain Netpoll-compatible listeners. `CreateListener` directly creates a non-blocking TCP or Unix socket listener. `ConvertListener` wraps an existing `net.Listener`, such as one created for TLS or testing purposes, into a Netpoll `Listener`. ### Methods - `CreateListener(protocol string, address string) (netpoll.Listener, error)` - `ConvertListener(listener net.Listener) (netpoll.Listener, error)` ### Parameters - `protocol` (string) - Required (for CreateListener) - The network protocol (e.g., "tcp", "unix"). - `address` (string) - Required (for CreateListener) - The network address to listen on. - `listener` (net.Listener) - Required (for ConvertListener) - An existing `net.Listener` to wrap. ### Request Example ```go // Create a new listener ln, err := netpoll.CreateListener("tcp", ":9090") // Convert an existing listener rawLn, _ := net.Listen("tcp", ":9091") npLn, err := netpoll.ConvertListener(rawLn) ``` ### Response - `netpoll.Listener` - A Netpoll-compatible listener. - `error` - An error if listener creation or conversion fails. ``` -------------------------------- ### Create a Reusable Dialer with netpoll.NewDialer Source: https://context7.com/cloudwego/netpoll/llms.txt Instantiate a `Dialer` using `NewDialer` to manage and reuse connections efficiently. This is useful for dependency injection and managing connection pools. ```go package main import ( "log" "time" "github.com/cloudwego/netpoll" ) func newConnectionPool(addr string, size int) []netpoll.Connection { dialer := netpoll.NewDialer() pool := make([]netpoll.Connection, 0, size) for i := 0; i < size; i++ { conn, err := dialer.DialConnection("tcp", addr, 3*time.Second) if err != nil { log.Printf("failed to dial connection %d: %v", i, err) continue } pool = append(pool, conn) } return pool } ``` -------------------------------- ### Netpoll Nocopy API Usage Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Illustrates the two-step process for Netpoll's nocopy APIs: reading data using Reader and releasing the buffer, and writing data using Writer, allocating, and flushing. ```go package main import ( "github.com/cloudwego/netpoll" ) func main() { var conn netpoll.Connection var reader, writer = conn.Reader(), conn.Writer() // reading buf, _ := reader.Next(n) ... parse the read data ... reader.Release() // writing var write_data []byte ... make the write data ... alloc, _ := writer.Malloc(len(write_data)) copy(alloc, write_data) // write data writer.Flush() } ``` -------------------------------- ### netpoll.NewEventLoop — Create a NIO Server Source: https://context7.com/cloudwego/netpoll/llms.txt Constructs an event-driven server that accepts connections and handles incoming data with a provided request handler and optional configuration callbacks. ```APIDOC ## netpoll.NewEventLoop ### Description Creates a new Netpoll event loop, which acts as a server. It takes an `OnRequest` handler that is invoked for each new incoming data on a connection. Various functional options can be provided to configure callbacks for connection preparation, connection establishment, disconnection, and timeouts. ### Parameters #### `OnRequest` Handler - `onRequest` (func(context.Context, netpoll.Connection) error) - Required - A callback function executed when new data is received on a connection. #### Options - `netpoll.WithOnPrepare(func(netpoll.Connection) context.Context)` - Optional - A callback function executed immediately after a connection is accepted, before any data is received. Useful for rate-limiting or attaching request-scoped metadata. - `netpoll.WithOnConnect(func(context.Context, netpoll.Connection) context.Context)` - Optional - A callback function executed when a new connection is established. - `netpoll.WithOnDisconnect(func(context.Context, netpoll.Connection))` - Optional - A callback function executed when a connection is closed. - `netpoll.WithReadTimeout(time.Duration)` - Optional - Sets the read timeout for connections. - `netpoll.WithIdleTimeout(time.Duration)` - Optional - Sets the idle timeout for connections. ### Request Example ```go listener, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } eventLoop, err := netpoll.NewEventLoop( onRequest, netpoll.WithOnPrepare(onPrepare), netpoll.WithOnConnect(onConnect), netpoll.WithOnDisconnect(onDisconnect), netpoll.WithReadTimeout(10*time.Second), netpoll.WithIdleTimeout(2*time.Minute), ) if err != nil { log.Fatal(err) } // Serve blocks until error or Shutdown if err := eventLoop.Serve(listener); err != nil { log.Println("Server stopped:", err) } ``` ### Response #### Success Response - `eventLoop` (netpoll.EventLoop) - The created event loop instance. - `err` (error) - An error if the event loop could not be created. ``` -------------------------------- ### Create a Client TCP Connection with netpoll.DialConnection Source: https://context7.com/cloudwego/netpoll/llms.txt Use `DialConnection` for a convenient way to establish TCP or Unix client connections. It returns a `netpoll.Connection` for direct use of nocopy APIs. Ensure to set read timeouts and handle connection errors. ```go package main import ( "context" "encoding/binary" "log" "time" "github.com/cloudwego/netpoll" ) func main() { conn, err := netpoll.DialConnection("tcp", "127.0.0.1:8080", 5*time.Second) if err != nil { log.Fatal("dial failed:", err) } defer conn.Close() conn.SetReadTimeout(10 * time.Second) // Send a framed message msg := []byte("hello netpoll") writer := conn.Writer() buf, _ := writer.Malloc(4 + len(msg)) binary.BigEndian.PutUint32(buf[:4], uint32(len(msg))) copy(buf[4:], msg) if err := writer.Flush(); err != nil { log.Fatal("flush failed:", err) } // Read the echoed response reader := conn.Reader() header, err := reader.Next(4) if err != nil { log.Fatal("read header failed:", err) } respLen := binary.BigEndian.Uint32(header) body, err := reader.ReadBinary(int(respLen)) // returns a copy, safe after Release if err != nil { log.Fatal("read body failed:", err) } reader.Release() log.Printf("Response: %s", body) // Output: Response: hello netpoll } ``` -------------------------------- ### Create Standalone Zero-Copy Buffer with netpoll.NewLinkBuffer Source: https://context7.com/cloudwego/netpoll/llms.txt Use NewLinkBuffer to create a standalone LinkBuffer outside of a live connection. This is useful for unit tests, message serialization, or building in-memory pipelines. The buffer has an initial capacity and supports writing and reading without data copying. ```go package main import ( "fmt" "github.com/cloudwego/netpoll" ) func main() { buf := netpoll.NewLinkBuffer(1024) // initial capacity 1KB // Write into the buffer buf.WriteString("GET / HTTP/1.1\r\n") buf.WriteString("Host: example.com\r\n") buf.WriteString("\r\n") buf.Flush() fmt.Println("Buffered bytes:", buf.Len()) // Buffered bytes: 38 // Read back without copying line, _ := buf.Until('\n') fmt.Printf("First line: %q\n", line) // First line: "GET / HTTP/1.1\r\n" buf.Release() } ``` -------------------------------- ### Shutdown Netpoll Server Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Shows how to gracefully shut down the Netpoll server using the Shutdown function with a context for timeout. ```go package main import ( "context" "time" "github.com/cloudwego/netpoll" ) var eventLoop netpoll.EventLoop func main() { // stop server ... ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() eventLoop.Shutdown(ctx) } ``` -------------------------------- ### Limit Go Process CPU Usage with taskset Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Use the 'taskset' command to restrict the number of CPU cores a Go process can utilize, preventing performance degradation from excessive pollers on multi-core machines. ```shell taskset -c 0-3 $run_your_server ``` -------------------------------- ### netpoll.NewIOReader / NewIOWriter Source: https://context7.com/cloudwego/netpoll/llms.txt These adapter functions bridge Netpoll's nocopy interfaces with Go's standard io.Reader and io.Writer. This enables interoperability with libraries that expect standard interfaces. ```APIDOC ## netpoll.NewReader / NewWriter / NewReadWriter — io.Reader/Writer Adapters These adapter functions bridge Netpoll's nocopy interfaces with Go's standard `io.Reader` and `io.Writer`, enabling interoperability with libraries that expect standard interfaces. ### Usage Examples ```go package main import ( "compress/gzip" "io" "github.com/cloudwego/netpoll" ) func decompressFromConnection(conn netpoll.Connection) ([]byte, error) { // Wrap netpoll.Reader as io.Reader for gzip ioReader := netpoll.NewIOReader(conn.Reader()) gr, err := gzip.NewReader(ioReader) if err != nil { return nil, err } defer gr.Close() data, err := io.ReadAll(gr) conn.Reader().Release() return data, err } func compressToConnection(conn netpoll.Connection, data []byte) error { // Wrap netpoll.Writer as io.Writer for gzip ioWriter := netpoll.NewIOWriter(conn.Writer()) gw := gzip.NewWriter(ioWriter) if _, err := gw.Write(data); err != nil { return err } gw.Close() return conn.Writer().Flush() } ``` ``` -------------------------------- ### Enable Concurrent Writes with mux.NewShardQueue Source: https://context7.com/cloudwego/netpoll/llms.txt ShardQueue allows multiple goroutines to safely write to a single connection concurrently. It shards writes across multiple buckets and batches flushes automatically, making it suitable for multiplexed RPC connections with out-of-order responses. ```go package main import ( "sync" "time" "github.com/cloudwego/netpoll" "github.com/cloudwego/netpoll/mux" ) func handleMuxConnection(conn netpoll.Connection) { // Create a shard queue with mux.ShardSize shards (== GOMAXPROCS by default) queue := mux.NewShardQueue(mux.ShardSize, conn) defer queue.Close() var wg sync.WaitGroup // Simulate 100 concurrent goroutines all writing responses at once for i := 0; i < 100; i++ { wg.Add(1) seq := uint32(i) go func() { defer wg.Done() // Each goroutine adds a WriterGetter; ShardQueue handles batching & Flush queue.Add(func() (buf netpoll.Writer, isNil bool) { lb := netpoll.NewLinkBuffer() lb.WriteString("response-") lb.WriteByte(byte(seq)) lb.Flush() return lb, false }) time.Sleep(time.Millisecond) // simulate work }() } wg.Wait() } ``` -------------------------------- ### Configure Per-Connection Timeouts in Netpoll Source: https://context7.com/cloudwego/netpoll/llms.txt Set read, write, and idle timeouts for individual connections. These can override global EventLoop defaults. ```go func onPrepare(conn netpoll.Connection) context.Context { // Tight read deadline for untrusted clients conn.SetReadTimeout(5 * time.Second) // Allow slow writes up to 30 seconds conn.SetWriteTimeout(30 * time.Second) // Close connections idle for more than 5 minutes (uses TCP KeepAlive) conn.SetIdleTimeout(5 * time.Minute) return context.Background() } ``` -------------------------------- ### Connection.Reader Source: https://context7.com/cloudwego/netpoll/llms.txt `Connection.Reader()` returns a `Reader` backed by the connection's internal `LinkBuffer`. All read methods operate directly on the buffer with zero-copy semantics. `Release` must be called after the data is no longer needed. ```APIDOC ## Connection.Reader — Nocopy Read Interface ### Description `Connection.Reader()` returns a `Reader` backed by the connection's internal `LinkBuffer`. All read methods (`Next`, `Peek`, `Skip`, `Until`, `ReadString`, `ReadBinary`, `ReadByte`, `Slice`) operate directly on the buffer with zero-copy semantics. `Release` must be called after the data is no longer needed. ### Method `conn.Reader() netpoll.Reader ### Usage ```go reader := conn.Reader() // Peek without advancing magic, err := reader.Peek(2) // Skip bytes reader.Skip(2) // Read until a delimiter line, err := reader.Until('\n') // Slice out a sub-reader subReader, err := reader.Slice(payloadSize) // Release the buffer when done reader.Release() ``` ``` -------------------------------- ### Configure Netpoll Poller Load Balancing Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Sets the connection load balancing strategy across multiple pollers. Supports Random and RoundRobin. RoundRobin is the default. ```go package main import ( "github.com/cloudwego/netpoll" ) func init() { netpoll.SetLoadBalance(netpoll.Random) // or netpoll.SetLoadBalance(netpoll.RoundRobin) } ``` -------------------------------- ### netpoll.NewLinkBuffer Source: https://context7.com/cloudwego/netpoll/llms.txt Creates a standalone LinkBuffer that implements both Reader and Writer interfaces. This is useful for scenarios outside of live connections, such as unit testing, message serialization, or building in-memory pipelines. ```APIDOC ## netpoll.NewLinkBuffer — Standalone Zero-Copy Buffer `NewLinkBuffer` creates a standalone `LinkBuffer` that implements both `Reader` and `Writer`. It is useful outside of a live connection context — for example, in unit tests, message serialization, or building in-memory pipelines. ### Usage Example ```go package main import ( "fmt" "github.com/cloudwego/netpoll" ) func main() { buf := netpoll.NewLinkBuffer(1024) // initial capacity 1KB // Write into the buffer buf.WriteString("GET / HTTP/1.1\r\n") buf.WriteString("Host: example.com\r\n") buf.WriteString("\r\n") buf.Flush() fmt.Println("Buffered bytes:", buf.Len()) // Buffered bytes: 38 // Read back without copying line, _ := buf.Until('\n') fmt.Printf("First line: %q\n", line) // First line: "GET / HTTP/1.1\r\n" buf.Release() } ``` ``` -------------------------------- ### Configure Connection Request Callback in Netpoll Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Register an OnRequest callback for server-side EventLoop creation or set it on a client-side connection using Connection.SetOnRequest. This callback is triggered on incoming data. ```go package main import ( "context" "github.com/cloudwego/netpoll" ) func main() { var onRequest netpoll.OnRequest = handler // 1. on server side evl, _ := netpoll.NewEventLoop(onRequest, opts...) ... // 2. on client side conn, _ := netpoll.DialConnection(network, address, timeout) conn.SetOnRequest(handler) ... } func handler(ctx context.Context, connection netpoll.Connection) (err error) { ... handling ... return nil } ``` -------------------------------- ### Graceful Server Shutdown with eventLoop.Shutdown Source: https://context7.com/cloudwego/netpoll/llms.txt Stops the server from accepting new connections and waits for active connections to finish. Honors the deadline set by the provided context. This function should be called in response to OS signals like SIGINT or SIGTERM. ```go package main import ( "context" "log" "os" "os/signal" "syscall" "time" "github.com/cloudwego/netpoll" ) func gracefulShutdown(eventLoop netpoll.EventLoop) { quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <- log.Println("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := eventLoop.Shutdown(ctx); err != nil { log.Printf("Shutdown error: %v", err) } else { log.Println("Server exited cleanly") } } ``` -------------------------------- ### Register Connection Close Callbacks with netpoll Source: https://context7.com/cloudwego/netpoll/llms.txt Register callbacks to execute when a connection is closed. Multiple callbacks are supported and executed in LIFO order. ```go func onConnect(ctx context.Context, conn netpoll.Connection) context.Context { // Associate a session with this connection session := newSession(conn.RemoteAddr().String()) conn.AddCloseCallback(func(c netpoll.Connection) error { session.Cleanup() log.Printf("Session for %s cleaned up", c.RemoteAddr()) return nil }) // Multiple callbacks are supported and executed in LIFO order conn.AddCloseCallback(func(c netpoll.Connection) error { metrics.RecordDisconnect(c.RemoteAddr().String()) return nil }) return context.WithValue(ctx, "session", session) } ``` -------------------------------- ### Connection.SetOnRequest Source: https://context7.com/cloudwego/netpoll/llms.txt Replaces the OnRequest handler for a specific connection. Useful for dynamic handler changes based on protocol negotiation or other conditions. ```APIDOC ## Connection.SetOnRequest ### Description Replaces the `OnRequest` handler for a specific connection. This is particularly useful on the client side or in proxy scenarios where message handling logic needs to change dynamically. ### Method `SetOnRequest` ### Parameters - `handler` (func(context.Context, netpoll.Connection) error) - Required - The new handler function to be set for requests. ### Request Example ```go conn.SetOnRequest(handleV1) ``` ### Response No explicit response. The handler is updated for subsequent requests on the connection. ``` -------------------------------- ### mux.NewShardQueue Source: https://context7.com/cloudwego/netpoll/llms.txt Enables multiple goroutines to safely write to a single connection concurrently. It shards writes across N lock buckets and batches flushes automatically, making it ideal for multiplexed RPC connections where responses arrive out-of-order. ```APIDOC ## mux.NewShardQueue — Concurrent Write Multiplexer `ShardQueue` (in the `mux` sub-package) enables multiple goroutines to safely write to a single connection concurrently. It shards writes across `N` lock buckets and batches flushes automatically, making it ideal for multiplexed RPC connections where responses arrive out-of-order. ### Usage Example ```go package main import ( "sync" "time" "github.com/cloudwego/netpoll" "github.com/cloudwego/netpoll/mux" ) func handleMuxConnection(conn netpoll.Connection) { // Create a shard queue with mux.ShardSize shards (== GOMAXPROCS by default) queue := mux.NewShardQueue(mux.ShardSize, conn) defer queue.Close() var wg sync.WaitGroup // Simulate 100 concurrent goroutines all writing responses at once for i := 0; i < 100; i++ { wg.Add(1) seq := uint32(i) go func() { defer wg.Done() // Each goroutine adds a WriterGetter; ShardQueue handles batching & Flush queue.Add(func() (buf netpoll.Writer, isNil bool) { lb := netpoll.NewLinkBuffer() lb.WriteString("response-") lb.WriteByte(byte(seq)) lb.Flush() return lb, false }) time.Sleep(time.Millisecond) // simulate work }() } wg.Wait() } ``` ``` -------------------------------- ### Configure Connection Read Timeout in Netpoll Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Set the read timeout for a connection using Connection.SetReadTimeout or during EventLoop creation with netpoll.WithReadTimeout. Read timeout prevents indefinite blocking on reads. ```go package main import ( "github.com/cloudwego/netpoll" ) func main() { var conn netpoll.Connection // 1. setting by Connection conn.SetReadTimeout(timeout) // or // 2. setting with Option netpoll.NewEventLoop(handler, netpoll.WithReadTimeout(timeout)) ... } ``` -------------------------------- ### eventLoop.Shutdown — Graceful Server Shutdown Source: https://context7.com/cloudwego/netpoll/llms.txt Stops the server from accepting new connections and gracefully shuts down active connections within a specified context deadline. ```APIDOC ## eventLoop.Shutdown ### Description Initiates a graceful shutdown of the Netpoll server. This method stops the server from accepting new connections and waits for existing connections to complete their operations before terminating. The shutdown process respects the deadline provided by the `context.Context`. ### Method - `Shutdown(ctx context.Context) error` ### Parameters - `ctx` (context.Context) - Required - A context that can be used to set a deadline for the shutdown process. If the deadline is exceeded, the shutdown may be aborted. ### Request Example ```go quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit log.Println("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := eventLoop.Shutdown(ctx); err != nil { log.Printf("Shutdown error: %v", err) } else { log.Println("Server exited cleanly") } ``` ### Response #### Success Response (200) - `nil` - Indicates that the shutdown process completed successfully within the context's deadline. #### Error Response - `error` - An error object if the shutdown process failed or was interrupted. ``` -------------------------------- ### Push changes to GitHub Source: https://github.com/cloudwego/netpoll/blob/main/CONTRIBUTING.md After committing your changes, push your feature branch to your forked GitHub repository. This makes your changes available for a pull request. ```bash git push origin my-fix-branch ``` -------------------------------- ### Create a new Git branch Source: https://github.com/cloudwego/netpoll/blob/main/CONTRIBUTING.md When contributing, create a new git branch from the main branch to isolate your changes. This helps maintain a clean main branch. ```bash git checkout -b my-fix-branch main ``` -------------------------------- ### Connection.SetReadTimeout, Connection.SetWriteTimeout, Connection.SetIdleTimeout Source: https://context7.com/cloudwego/netpoll/llms.txt Configures per-connection timeouts for read operations, write operations, and idle detection. These can override global EventLoop defaults. ```APIDOC ## Connection.SetReadTimeout / SetWriteTimeout / SetIdleTimeout ### Description These methods control per-connection timeouts for read blocking, write blocking, and TCP KeepAlive-based idle detection. They allow for fine-grained control over connection behavior, overriding defaults set on the `EventLoop`. ### Methods - `SetReadTimeout(timeout time.Duration)` - `SetWriteTimeout(timeout time.Duration)` - `SetIdleTimeout(timeout time.Duration)` ### Parameters - `timeout` (time.Duration) - Required - The duration for the respective timeout. ### Request Example ```go conn.SetReadTimeout(5 * time.Second) conn.SetWriteTimeout(30 * time.Second) conn.SetIdleTimeout(5 * time.Minute) ``` ### Response No explicit response. Timeouts are applied to the connection. ``` -------------------------------- ### Configure Connection Idle Timeout in Netpoll Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Set the idle timeout for a connection using Connection.SetIdleTimeout or during EventLoop creation with netpoll.WithIdleTimeout. This helps proactively close inactive connections. ```go package main import ( "github.com/cloudwego/netpoll" ) func main() { var conn netpoll.Connection // 1. setting by Connection conn.SetIdleTimeout(timeout) // or // 2. setting with Option netpoll.NewEventLoop(handler, netpoll.WithIdleTimeout(timeout)) ... } ``` -------------------------------- ### netpoll.NewDialer Source: https://context7.com/cloudwego/netpoll/llms.txt `NewDialer` returns a `Dialer` instance that can dial multiple connections. Useful when you need to manage dialing as an injectable dependency. ```APIDOC ## netpoll.NewDialer — Reusable Dialer ### Description `NewDialer` returns a `Dialer` instance that can dial multiple connections. Useful when you need to manage dialing as an injectable dependency. ### Method `netpoll.NewDialer()` ### Response #### Success Response (Dialer) - **dialer** (`netpoll.Dialer`) - A reusable Dialer instance. ### Usage Example ```go dialer := netpoll.NewDialer() conn, err := dialer.DialConnection("tcp", "127.0.0.1:8080", 3*time.Second) if err != nil { log.Fatal("dial failed:", err) } ``` ``` -------------------------------- ### Connection.AddCloseCallback Source: https://context7.com/cloudwego/netpoll/llms.txt Registers callbacks to be executed when a connection is closed. Multiple callbacks can be added and are executed in LIFO order. ```APIDOC ## Connection.AddCloseCallback ### Description Registers one or more callbacks that are called when the connection is closed (either by peer or self). This allows for straightforward resource cleanup. ### Method `AddCloseCallback` ### Parameters - `callback` (func(netpoll.Connection) error) - Required - The function to be called upon connection closure. ### Request Example ```go conn.AddCloseCallback(func(c netpoll.Connection) error { session.Cleanup() log.Printf("Session for %s cleaned up", c.RemoteAddr()) return nil }) ``` ### Response No explicit response, but callbacks are executed upon connection closure. ``` -------------------------------- ### Configure Netpoll Number of Pollers Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Sets the number of epoll instances Netpoll creates. By default, it adjusts to the number of P (runtime.GOMAXPROCS(0)). For heavy I/O services, explicitly set this value. ```go package main import ( runtime "github.com/cloudwego/netpoll" ) func init() { netpoll.SetNumLoops(runtime.GOMAXPROCS(0)) } ``` -------------------------------- ### Dynamically Replace Request Handler in Netpoll Source: https://context7.com/cloudwego/netpoll/llms.txt Replace the OnRequest handler for a specific connection. Useful for client-side or proxy scenarios where message handling logic changes. ```go func onRequest(ctx context.Context, conn netpoll.Connection) error { reader := conn.Reader() // Read the handshake / protocol negotiation message versionByte, err := reader.ReadByte() reader.Release() if err != nil { return err } // Swap in the appropriate handler based on negotiated protocol version switch versionByte { case 1: conn.SetOnRequest(handleV1) case 2: conn.SetOnRequest(handleV2) default: conn.Close() } return nil } func handleV1(ctx context.Context, conn netpoll.Connection) error { // v1 protocol handler return nil } func handleV2(ctx context.Context, conn netpoll.Connection) error { // v2 protocol handler return nil } ``` -------------------------------- ### netpoll.DialConnection Source: https://context7.com/cloudwego/netpoll/llms.txt `DialConnection` is the top-level convenience function for dialing TCP or Unix connections from the client side. It returns a full `netpoll.Connection`, not a `net.Conn`, enabling direct use of nocopy APIs. ```APIDOC ## netpoll.DialConnection — Create a Client Connection ### Description `DialConnection` is the top-level convenience function for dialing TCP or Unix connections from the client side. It returns a full `netpoll.Connection`, not a `net.Conn`, enabling direct use of nocopy APIs. ### Method `netpoll.DialConnection(protocol, address, timeout)` ### Parameters #### Path Parameters - **protocol** (string) - Required - The network protocol (e.g., "tcp", "unix"). - **address** (string) - Required - The network address to connect to. - **timeout** (time.Duration) - Required - The maximum time to wait for the connection to establish. ### Request Example ```go conn, err := netpoll.DialConnection("tcp", "127.0.0.1:8080", 5*time.Second) if err != nil { log.Fatal("dial failed:", err) } defer conn.Close() ``` ### Response #### Success Response (Connection) - **conn** (`netpoll.Connection`) - A valid Netpoll connection object. - **err** (`error`) - An error if the connection failed, nil otherwise. #### Error Response - **err** (`error`) - Details about the connection failure. ``` -------------------------------- ### Add Connection Close Callback in Netpoll Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Add a CloseCallback to a Netpoll connection using Connection.AddCloseCallback. This callback is executed when the connection is closed, allowing for post-closure processing. ```go package main import ( "github.com/cloudwego/netpoll" ) func main() { var conn netpoll.Connection // add close callback var cb netpoll.CloseCallback = callback conn.AddCloseCallback(cb) ... } func callback(connection netpoll.Connection) error { return nil } ``` -------------------------------- ### Set Netpoll Number of Event Loops Source: https://github.com/cloudwego/netpoll/blob/main/docs/guide/guide_en.md Control the number of pollers Netpoll uses by calling netpoll.SetNumLoops. This is an alternative to GOMAXPROCS for tuning Netpoll's concurrency. ```go package main import ( "github.com/cloudwego/netpoll" ) func init() { netpoll.SetNumLoops(num_you_want) } ```