ioxide.file 0.0.2

dotnet add package ioxide.file --version 0.0.2
                    
NuGet\Install-Package ioxide.file -Version 0.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ioxide.file" Version="0.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ioxide.file" Version="0.0.2" />
                    
Directory.Packages.props
<PackageReference Include="ioxide.file" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ioxide.file --version 0.0.2
                    
#r "nuget: ioxide.file, 0.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ioxide.file@0.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ioxide.file&version=0.0.2
                    
Install as a Cake Addin
#tool nuget:?package=ioxide.file&version=0.0.2
                    
Install as a Cake Tool

ioxide

ioxide ioxide.pg ioxide.file ioxide.tls ioxide.redis

A shared-nothing io_uring runtime for .NET.

One ring per reactor thread - run one per core. HTTP, Postgres, and file I/O submit on that ring and resume inline on the same thread. No thread pool on the hot path. No native dependencies - raw syscalls, nothing else.

Linux 6.1+ · .NET 10 · status 0.0.2 - experimental

Documentation → - architecture, guides, the full picture

Quick start

dotnet run -c Release --project Playground                     # GET / → ok

PLAYGROUND_MODE=pg   dotnet run -c Release --project Playground  # SELECT 42 over the ring
PLAYGROUND_MODE=file dotnet run -c Release --project Playground  # static files off the ring

How it works

var reactor = new Reactor(id, new ServerConfig { Port = 8080 });

// Clients opened here ride this reactor's ring.
reactor.OnStart = r => PgPool.Start(r, pgOptions);

reactor.Handle = async (r, conn) =>
{
    var pool = r.GetService<PgPool>();

    // Carry for bytes a read leaves behind - the head of a split request.
    var inflight = new byte[16 * 1024];
    int inflightTail = 0;

    while (true)
    {
        // io_uring recv - resumes inline on the reactor.
        var snapshot = await conn.ReadAsync();

        var rings = conn.GetSnapshotMemories(snapshot);
        if (rings.Length > 0)
        {
            ReadOnlySequence<byte> data;
            if (inflightTail == 0 && rings.Length == 1)
            {
                // Hot path: one ring, no carry - a single zero-copy segment.
                data = new ReadOnlySequence<byte>(rings[0].Memory);
            }
            else if (inflightTail == 0)
            {
                // Several rings, no carry - chain them, still zero-copy.
                data = rings.ToReadOnlySequence();
            }
            else
            {
                // Cold path: the carry goes first so a split request reads whole.
                var first = new RingSegment(inflight.AsMemory(0, inflightTail), 0);
                var last  = first;
                for (int i = 0; i < rings.Length; i++)
                    last = last.Append(rings[i].Memory, rings[i].BufferId);
                data = new ReadOnlySequence<byte>(first, 0, last, last.Memory.Length);
            }

            // Walk every complete request; stop at the first partial one.
            // TryParseRequest, Request, and SqlFor are YOUR code - ioxide
            // hands you raw bytes and stays out of HTTP.
            long consumed = 0;
            bool respond  = false;
            while (TryParseRequest(data.Slice(consumed), out Request request, out long length))
            {
                consumed += length;

                // io_uring send + recv to Postgres, on the same ring.
                var rows = await pool.QueryAsync(SqlFor(request.Path));

                // ioxide doesn't speak HTTP for you - you write the bytes.
                string body = $"db={rows.Value}";
                conn.Write(Encoding.ASCII.GetBytes(
                    $"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: {body.Length}\r\n\r\n{body}"));
                respond = true;
            }

            // Whatever wasn't consumed (a partial request, or everything when
            // nothing completed) moves to the front of the carry - only then
            // do the buffers go back to the ring.
            ReadOnlySequence<byte> rest = data.Slice(consumed);
            rest.CopyTo(inflight);
            inflightTail = (int)rest.Length;

            conn.ReturnBuffers(rings);

            if (respond) await conn.FlushAsync();   // io_uring send, once per batch
        }

        if (snapshot.IsClosed)
        {
            conn.DecRef();
            return;
        }

        conn.ResetRead();
    }
};

// One reactor per core.
new Thread(reactor.Run).Start();

Every await above is a CQE on this core's ring. Nothing hops threads.

Projects

ioxide/        the engine - reactor, connection, IRingHost seam, client kit
ioxide.pg/     Postgres over the ring: pooled connections, ring-native connect
ioxide.file/   files over the ring: baked asset snapshots + positional reads
Playground/    runnable host (raw · pg · file · hop modes)
Research/      the experimental engines this was distilled from (not referenced)

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.0.2 0 6/11/2026
0.0.1 35 6/11/2026