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 )