Acme-Parataxis

 view release on metacpan or  search on metacpan

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

=pod

=encoding utf8

=head1 NAME

Acme::Parataxis::Compat - Transparent Gevent-Style Cooperative Unblocking of Builtins

=head1 SYNOPSIS

    use v5.40;
    use Acme::Parataxis qw[async fiber];

    # Must be installed at compile time, in a BEGIN block, above affected code:
    BEGIN { Acme::Parataxis->enable_transparent_unblocking() }

    async {
        my $sock = IO::Socket::INET->new( PeerAddr => 'example.com:80' ) or die $!;

        # Standard blocking builtins are now cooperative inside fibers:
        my $napper = fiber {
            sleep 0.05;    # yields to the scheduler; does not block the OS thread
            say 'f1: finished sleep';
        };

        my $reader = fiber {
            my $buf = q{};
            read( $sock, $buf, 64 );    # frames onto await_read; yields while waiting
            say "f2: read ${\length($buf)} bytes";
        };

        $napper->await;
        $reader->await;
    };

=head1 DESCRIPTION

C<Acme::Parataxis::Compat> provides an opt-in, C<gevent>-style compatibility layer for legacy synchronous code. By
installing C<CORE::GLOBAL> overrides for C<sleep>, C<read>, and C<sysread>, existing modules and synchronous loops run
cooperatively inside fibers without freezing the entire process:

=over

=item * C<sleep> becomes L<await_sleep|Acme::Parataxis/await_sleep>

The calling fiber yields for the requested duration while other fibers proceed. Fractional seconds are honored with
millisecond precision (C<sleep 0.05> sleeps 50ms, whereas C<CORE::sleep> truncates this to 0). When called outside a
fiber, it falls back immediately to C<CORE::sleep>. The C<$_> default argument is supported.

=item * C<read> and C<sysread> become non-blocking reads framed on L<await_read|Acme::Parataxis/await_read>

The fiber parks until the filehandle is reported readable, flips the handle non-blocking, reads available bytes, and
restores the original handle mode. B<It can return fewer bytes than requested>, exactly like a non-blocking socket
read; callers needing an exact byte count should loop.

=item * Everything else remains untouched

C<select>, C<alarm>, C<connect>, and C-level extensions like C<DBI> are not intercepted and remain blocking. Use
L<await_read|Acme::Parataxis/await_read>, L<await_write|Acme::Parataxis/await_write>, or L<Acme::Parataxis::Blocking>
for those.

=back

Nothing is modified unless you explicitly invoke C<enable_transparent_unblocking()>, and only code I<compiled after>
the call is affected. Perl resolves C<CORE::GLOBAL> overrides at parse time, so installation must take place within a
C<BEGIN> block placed above the target code. Outside of a running fiber, all three overrides delegate directly to the
native C<CORE::> builtins.

=head1 METHODS

=head2 C<< Acme::Parataxis->enable_transparent_unblocking( ) >>

    BEGIN { Acme::Parataxis->enable_transparent_unblocking() }
    # or:
    BEGIN { Acme::Parataxis::Compat->install() }

Installs the C<CORE::GLOBAL> overrides and returns C<1>. Idempotent.

=head2 C<< Acme::Parataxis->disable_transparent_unblocking( ) >>

    Acme::Parataxis->disable_transparent_unblocking();
    # or:
    Acme::Parataxis::Compat->disable();

Restores the global symbols to their pre-installation state. Safely clears internal subroutine depth tracking so Perl's
subroutine finalization does not trigger "Can't undef active subroutine" errors. Only code compiled I<after> this call
reverts to the builtins.

=head2 C<< Acme::Parataxis->transparent_unblocking( ) >>

    say 'Active' if Acme::Parataxis->transparent_unblocking();
    # or:
    say 'Active' if Acme::Parataxis::Compat->installed();

Returns true if the transparent unblocking overrides are currently installed.

=head1 Recipes



( run in 2.446 seconds using v1.01-cache-2.11-cpan-b554fb43c41 )