Data-ReqRep-Shared

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

        my $rep_fd = $srv->reply_eventfd;
        $srv->reply_notify;             # signal after reply
        $cli->eventfd;                  # create (maps to reply fd)
        $cli->eventfd_consume;          # drain in callback
        $cli->eventfd_set($fd);         # set inherited fd

    For cross-process use, create both eventfds before fork() so child
    inherits the fds:

        my $srv = Data::ReqRep::Shared->new($path, 1024, 64, 4096);
        my $req_fd = $srv->eventfd;
        my $rep_fd = $srv->reply_eventfd;

        if (fork() == 0) {
            my $cli = Data::ReqRep::Shared::Client->new($path);
            $cli->req_eventfd_set($req_fd);
            $cli->eventfd_set($rep_fd);
            $cli->send_notify($data);       # wakes server
            # EV::io $rep_fd for reply ...
            exit;
        }

        # parent = server
        my $w = EV::io $req_fd, EV::READ, sub {
            $srv->eventfd_consume;
            while (my ($req, $id) = $srv->recv) {
                $srv->reply($id, process($req));
            }
            $srv->reply_notify;
        };

  Crash Safety
    *   Stale mutex -- if a process dies holding the request queue mutex,
        other processes detect it via PID tracking and recover within 2
        seconds.

    *   Stale response slots -- if a client dies while holding a slot
        (ACQUIRED or READY state), the slot is reclaimed automatically
        during the next slot acquisition scan.

    *   ABA protection -- response slot IDs carry a generation counter. A
        cancelled-and-reacquired slot has a different generation, so stale
        "reply"/"get"/"cancel" calls are safely rejected.

  Tuning
    "req_cap" -- request queue capacity (power of 2). Higher for bursty
    workloads (1024-4096), lower for steady-state (64-256). Memory: 24
    bytes/slot + arena (Str) or 24 bytes/slot (Int).
    "resp_slots" -- max concurrent in-flight requests across all clients.
    One slot per outstanding async request. For synchronous req(), one per
    client suffices. Memory: 64 bytes/slot (Int) or (32 + "resp_size"
    rounded up to 64) bytes/slot (Str).
    "resp_size" -- max response payload bytes (Str only). Fixed per slot.
    Responses exceeding this croak. Pick the 99th percentile.
    "arena" -- request data arena bytes (Str only, default "req_cap * 256").
    Increase for large requests. Monitor "arena_used" in stats().

  Benchmarks
    Linux x86_64. Run "perl -Mblib bench/vs.pl 50000" to reproduce.

        SINGLE-PROCESS ECHO (200K iterations)
        ReqRep::Int (lock-free)    1.8M req/s
        ReqRep::Str (12B, mutex)   1.2M req/s
        ReqRep::Str batch (100x)   1.4M req/s

        CROSS-PROCESS ECHO (50K iterations, 12B payload)
        Pipe pair (1:1)            240K req/s
        Unix socketpair (1:1)      222K req/s
        ReqRep::Int                202K req/s  *
        ReqRep::Str                177K req/s  *
        IPC::Msg (SysV)            165K req/s
        TCP loopback               115K req/s
        MCE::Channel                96K req/s
        Socketpair via broker       82K req/s
        Forks::Queue (Shmem)         5K req/s

    "*" = MPMC with per-request reply routing. Pipes and sockets are faster
    for simple 1:1 echo but require dedicated fd pairs per client-worker
    connection and cannot do MPMC without a broker (which halves
    throughput).

SEE ALSO
    Data::Buffer::Shared - typed shared array

    Data::HashMap::Shared - concurrent hash table

    Data::Queue::Shared - FIFO queue

    Data::PubSub::Shared - publish-subscribe ring

    Data::Sync::Shared - synchronization primitives

    Data::Pool::Shared - fixed-size object pool

    Data::Stack::Shared - LIFO stack

    Data::Deque::Shared - double-ended queue

    Data::Log::Shared - append-only log (WAL)

    Data::Heap::Shared - priority queue

    Data::Graph::Shared - directed weighted graph

    Data::BitSet::Shared - shared bitset (lock-free per-bit ops)

    Data::RingBuffer::Shared - fixed-size overwriting ring buffer

AUTHOR
    vividsnow

LICENSE
    This is free software; you can redistribute it and/or modify it under
    the same terms as Perl itself.



( run in 0.801 second using v1.01-cache-2.11-cpan-71847e10f99 )