Class NioBackend

java.lang.Object
express.mvp.myra.transport.nio.NioBackend
All Implemented Interfaces:
TransportBackend, AutoCloseable

public final class NioBackend extends Object implements TransportBackend
NIO-based transport backend for portable, cross-platform I/O.

This backend uses traditional Java NIO (SocketChannel + Selector) and works on all platforms. While not as fast as io_uring, it provides reliable baseline performance with zero-allocation hot paths.

Performance Comparison with io_uring

NIO vs io_uring Feature Comparison
FeatureNIOio_uring
PlatformAll JVM platformsLinux 5.1+
Registered buffersNoYes (1.7x speedup)
Batch submissionNoYes (100x syscall reduction)
SQPOLL modeNoYes (zero syscall I/O)
Syscalls per op~1-2Amortized 0.01

Design Principles

  • Zero-allocation hot path: Pre-allocated completion ring buffer, cached ByteBuffer views via FFM's MemorySegment.asByteBuffer()
  • FFM-first: Works directly with MemorySegment, avoiding byte[] copies
  • Thread-safe: Atomic state management, lock-free completion ring
  • API consistent: Same interface as IoUringBackend for seamless fallback

When to Use NIO

  • Cross-platform compatibility is required
  • Running on non-Linux systems (macOS, Windows)
  • io_uring is unavailable (older kernel or missing liburing)
  • Development/testing on local machines

Architecture

┌─────────────────────────────────────────────────────────┐
│                      NioBackend                         │
├─────────────────────────────────────────────────────────┤
│                                                         │
│   ┌─────────────┐    ┌─────────────┐                   │
│   │ Completion  │    │  Selector   │                   │
│   │ Ring Buffer │    │  (epoll/    │                   │
│   │ (immediate) │    │   kqueue)   │                   │
│   └─────────────┘    └─────────────┘                   │
│          │                  │                          │
│          ▼                  ▼                          │
│   ┌─────────────────────────────────────┐              │
│   │         poll() / waitFor()          │              │
│   │  Delivers completions to handler    │              │
│   └─────────────────────────────────────┘              │
│                                                         │
└─────────────────────────────────────────────────────────┘
See Also:
  • Constructor Details

    • NioBackend

      public NioBackend()
  • Method Details

    • initialize

      public void initialize(TransportConfig config)
      Description copied from interface: TransportBackend
      Initializes the backend with the given configuration.

      This is called once during transport creation. Implementations should allocate resources, initialize the I/O subsystem, and prepare for operations.

      Specified by:
      initialize in interface TransportBackend
      Parameters:
      config - the transport configuration
    • registerBufferPool

      public void registerBufferPool(RegisteredBufferPool bufferPool)
      Description copied from interface: TransportBackend
      Registers a buffer pool with this backend for zero-copy I/O.

      For io_uring, this calls io_uring_register_buffers() to pre-register memory regions with the kernel. For other backends, this may be a no-op.

      Specified by:
      registerBufferPool in interface TransportBackend
      Parameters:
      bufferPool - the buffer pool to register
    • connect

      public void connect(SocketAddress remoteAddress, long token)
      Description copied from interface: TransportBackend
      Connects to a remote endpoint asynchronously.
      Specified by:
      connect in interface TransportBackend
      Parameters:
      remoteAddress - the remote address to connect to
      token - the token identifying the operation
    • bind

      public void bind(SocketAddress localAddress)
      Description copied from interface: TransportBackend
      Binds to a local address for accepting connections (server mode).
      Specified by:
      bind in interface TransportBackend
      Parameters:
      localAddress - the local address to bind to
    • accept

      public void accept(long token)
      Description copied from interface: TransportBackend
      Accepts an incoming connection (server mode).
      Specified by:
      accept in interface TransportBackend
      Parameters:
      token - the token identifying the operation
    • send

      public void send(RegisteredBuffer buffer, long token)
      Description copied from interface: TransportBackend
      Sends data using a registered buffer (zero-copy).

      For io_uring, this uses io_uring_prep_send_fixed() with the buffer index. For other backends, this may fall back to a regular send.

      Specified by:
      send in interface TransportBackend
      Parameters:
      buffer - the registered buffer containing data to send
      token - the token identifying the operation
    • send

      public void send(MemorySegment data, int length, long token)
      Description copied from interface: TransportBackend
      Sends data using a raw memory segment.

      This is a fallback for non-registered buffers. Less efficient than TransportBackend.send(RegisteredBuffer, long) but more flexible.

      Specified by:
      send in interface TransportBackend
      Parameters:
      data - the memory segment containing data to send
      length - the number of bytes to send
      token - the token identifying the operation
    • receive

      public void receive(RegisteredBuffer buffer, long token)
      Description copied from interface: TransportBackend
      Receives data into a registered buffer (zero-copy).

      For io_uring, this uses io_uring_prep_recv_fixed() with the buffer index.

      Specified by:
      receive in interface TransportBackend
      Parameters:
      buffer - the registered buffer to receive into
      token - the token identifying the operation
    • receive

      public void receive(MemorySegment data, int maxLength, long token)
      Description copied from interface: TransportBackend
      Receives data into a raw memory segment.
      Specified by:
      receive in interface TransportBackend
      Parameters:
      data - the memory segment to receive into
      maxLength - the maximum number of bytes to receive
      token - the token identifying the operation
    • submitBatch

      public int submitBatch()
      Description copied from interface: TransportBackend
      Submits all queued operations in a batch.

      For io_uring, this calls io_uring_submit() to submit all queued operations with a single syscall. This is the key to achieving 100x syscall reduction.

      For NIO, this is typically a no-op since NIO doesn't support batching.

      Specified by:
      submitBatch in interface TransportBackend
      Returns:
      the number of operations submitted
    • poll

      public int poll(CompletionHandler handler)
      Description copied from interface: TransportBackend
      Polls for completions without blocking.

      For io_uring, this calls io_uring_peek_cqe() to check for completed operations. For NIO, this may use a Selector with 0 timeout.

      Specified by:
      poll in interface TransportBackend
      Parameters:
      handler - the handler to call for each completion
      Returns:
      the number of operations completed
    • waitForCompletion

      public int waitForCompletion(long timeoutMillis, CompletionHandler handler)
      Description copied from interface: TransportBackend
      Waits for at least one operation to complete.

      This blocks until at least one queued operation completes.

      Specified by:
      waitForCompletion in interface TransportBackend
      Parameters:
      timeoutMillis - the maximum time to wait in milliseconds (0 = forever)
      handler - the handler to call for each completion
      Returns:
      the number of operations completed
    • createFromAccepted

      public TransportBackend createFromAccepted(int handle)
      Description copied from interface: TransportBackend
      Creates a new backend instance from an accepted connection handle.

      For io_uring, the handle is the file descriptor. For NIO, the handle is an index or reference to the accepted channel.

      Specified by:
      createFromAccepted in interface TransportBackend
      Parameters:
      handle - the handle returned by the accept completion
      Returns:
      a new TransportBackend for the accepted connection
    • supportsRegisteredBuffers

      public boolean supportsRegisteredBuffers()
      Description copied from interface: TransportBackend
      Returns whether this backend supports registered buffers.
      Specified by:
      supportsRegisteredBuffers in interface TransportBackend
      Returns:
      true if registered buffers are supported
    • supportsBatchSubmission

      public boolean supportsBatchSubmission()
      Description copied from interface: TransportBackend
      Returns whether this backend supports batch submission.
      Specified by:
      supportsBatchSubmission in interface TransportBackend
      Returns:
      true if batch submission is supported
    • supportsTLS

      public boolean supportsTLS()
      Description copied from interface: TransportBackend
      Returns whether this backend supports TLS/SSL.
      Specified by:
      supportsTLS in interface TransportBackend
      Returns:
      true if TLS is supported
    • getBackendType

      public String getBackendType()
      Description copied from interface: TransportBackend
      Returns the backend type identifier.
      Specified by:
      getBackendType in interface TransportBackend
      Returns:
      the backend type (e.g., "io_uring", "nio", "xdp")
    • getStats

      public BackendStats getStats()
      Description copied from interface: TransportBackend
      Returns statistics about backend operations.
      Specified by:
      getStats in interface TransportBackend
      Returns:
      backend statistics including operation counts, errors, etc.
    • close

      public void close()
      Description copied from interface: TransportBackend
      Closes the backend and releases all resources.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface TransportBackend
    • getConnectionState

      public NioBackend.ConnectionState getConnectionState()
      Gets the current connection state.
      Returns:
      the connection state