Acme-Parataxis

 view release on metacpan or  search on metacpan

lib/Acme/Parataxis.pod  view on Meta::CPAN

            await_sleep(1000);
            say '  Task 1: Waking up';
            return 'Coffee!';
        };
        my $f2 = fiber {
            say '  Task 2: Calculating... (simulated CPU work)';
            my $sum = 0;
            for ( 1 .. 100 ) {
                $sum += $_;
                yield;    # yield control back to the scheduler
            }
            say '  Task 2: Complete. Will return ' . $sum;
            return $sum;
        };

        # await works on fibers and futures
        say 'Result 1: ' . await($f1);
        say 'Result 2: ' . await($f2);
    };
    # Output:
    # Main task started
    #   Task 1: Sleeping...
    #   Task 2: Calculating... (simulated CPU work)
    #   Task 2: Complete. Will return 5050
    #   Task 1: Waking up
    # Result 1: Coffee!
    # Result 2: 5050

=head1 DESCRIPTION

C<Acme::Parataxis> brings stackful cooperative multitasking (green threads or fibers) and native thread-pool offloading
to Perl. It combines cooperative multitasking (fibers) with a preemptive native thread pool.

All Perl code runs within a fiber: a user-space thread of execution with its own C-level execution context and
independent Perl interpreter stacks (argument, mark, scope, save, and mortal stacks). Unlike preemptive OS threads,
fibers are cooperatively scheduled: a fiber runs until it yields or pauses for a blocking operation. Because scheduling
is deterministic, mutable state shared across fibers requires no mutex locks unless an operation suspends across a
yield boundary.

When a fiber encounters a blocking task such as sleeping or waiting on a file descriptor, it will not stall the Perl
interpreter. Instead, the calling fiber is suspended, the blocking wait is offloaded to a background OS worker thread
in a native C thread pool (or an attached event loop), and the scheduler resumes other runnable fibers. Once the
background operation completes, the parked fiber is re-enqueued and resumes with its result.

The core exports the scheduler interface (C<async>, C<run>), fiber lifecycle tools (C<fiber>, C<spawn>, C<yield>,
C<await>), async I/O primitives (C<await_sleep>, C<await_read>, C<await_write>), structured concurrency (C<nursery>),
and cooperative cancellation (C<with_timeout>, C<with_cancel>).

Higher-level abstractions are separated into dedicated companion classes:

=over

=item * L<Acme::Parataxis::Actor> - Isolated state behind a private fiber with an incoming mailbox.

=item * L<Acme::Parataxis::Channel> - Bounded CSP message queues with backpressure and multiplexed C<select>.

=item * L<Acme::Parataxis::Blocking> - Offload heavy CPU work to cloned interpreters or forked processes.

=item * L<Acme::Parataxis::Future> - Single-assignment asynchronous values and completion hooks.

=item * L<Acme::Parataxis::Stream> - FRP-style streaming pipelines over bounded channels.

=item * L<Acme::Parataxis::Sync> - Mutexes, read/write locks, wait groups, barriers, and initializers.

=item * L<Acme::Parataxis::TVar> - Software Transactional Memory (STM) with automatic retry on conflict.

=item * L<Acme::Parataxis::Compat> - Gevent-style transparent unblocking for legacy C<sleep> and C<read> calls.

=back

This project was greatly inspired by the concurrency system for the L<Wren|https://wren.io/concurrency.html>
programming language and my own curiosity; I wanted to see how hard it would be to fiddle with perl's core from an FFI
and nothing requires more fiddling than picking up the full context and swapping it around at runtime.

=head1 FUNCTIONS

Importable individually or with the C<:all> tag.

=head2 C<async { ... }>

    async {
        # scheduler starts, executes block as the root fiber, and stops when finished
    };

Convenience wrapper around C<run()>. Executes the provided code block as the initial root fiber of a new scheduler
session and stops the scheduler once the block returns or dies.

=head2 C<fiber { ... }>

    my $f = fiber {
        my $val = do_work();
        return $val;
    };

Creates and schedules a new fiber. An alias for C<spawn()>. Returns the C<Acme::Parataxis> fiber object, which
implements the Future interface (C<await>, C<result>, C<error>, C<on_ready>).

=head2 C<await( $target )>

    my $val = await($fiber_or_future);

Suspends the current fiber until C<$target> completes. C<$target> may be an C<Acme::Parataxis> fiber, an
L<Acme::Parataxis::Future>, or an L<Acme::Parataxis::Monitor>. Returns the resolution value or rethrows the target's
death error in the caller.

=head2 C<yield( [@args] )>

    yield();
    my $reply = yield('hello');

Suspends the current fiber and returns control to the scheduler. If C<@args> are passed, they are delivered to the
context that next calls or resumes this fiber.

=head2 C<await_sleep( $ms )>

    await_sleep(250);    # sleep 250 milliseconds

Cooperatively suspends the current fiber for C<$ms> milliseconds. The delay is handed to the native thread pool or
attached driver, allowing other fibers to execute.

=head2 C<await_read( $fh, [$timeout_ms = 5000] )>

    my $ready = await_read( $socket, 2000 );

Suspends the current fiber until C<$fh> is ready to read or the timeout expires. Returns C<1> on readiness, C<-1> on
timeout or unwatchable handle.



( run in 1.978 second using v1.01-cache-2.11-cpan-b554fb43c41 )