NAME
Acme::Parataxis::Future - Single-Assignment Values for Fiber Coordination
SYNOPSIS
use v5.40;
use Acme::Parataxis qw[async fiber];
use Acme::Parataxis::Future;
my $future = Acme::Parataxis::Future->new;
async {
# Consumer: parks until the future resolves
fiber {
say 'Waiting for answer...';
my $val = $future->await;
say "Got result: $val";
};
# Producer: sets the result from another fiber
fiber {
$future->set_result(42);
};
};
DESCRIPTION
An Acme::Parataxis::Future represents a value that will become available at a later time. It acts as a single-assignment coordination point between fibers: producers fulfill the future with a result or error, and consumers park on it until it is ready.
Key characteristics:
Zero polling: Calling
$future->awaitsuspends the calling fiber in the scheduler. Whenset_resultorset_erroris called, all waiting fibers are re-enqueued onto the run queue in a single pass.Single resolution: A future can be fulfilled exactly once. Attempting to call
set_resultorset_erroron an already-ready future dies immediately.Cancellable waits: Fibers parked in
await()can be interrupted by with_timeout or Acme::Parataxis::CancellationToken. If interrupted, the fiber is safely unregistered from the future's waiter list, preventing stale wakeups.Composable: Futures compose with Acme::Parataxis->wait_all and Acme::Parataxis->wait_any.
Acme::Parataxisfiber objects themselves implement this same Future interface.
METHODS
new( )
my $fut = Acme::Parataxis::Future->new;
Constructs a new, unfulfilled future.
await( )
my $val = $fut->await;
Suspends the current fiber until the future is ready.
If the future is already ready, returns the result immediately without yielding.
If the future resolves via
set_result($val), returns$val.If the future fails via
set_error($err), dies with$errin the awaiting fiber.
Must be called from inside a scheduled fiber (croaks otherwise).
result( )
my $val = $fut->result;
Returns the resolved value immediately. Croaks with "Future not ready" if the future is unfulfilled, or croaks with the stored error if the future failed. Unlike await(), result() does not park—use this when is_ready() is already known to be true or inside an on_ready callback.
set_result( $value )
$fut->set_result( { status => 'ok' } );
Fulfills the future with $value. Transitions is_ready to true, fires all callbacks registered via on_ready(), and wakes every fiber currently parked in await(). Dies if the future is already ready.
set_error( $error )
$fut->set_error("Connection refused");
Fails the future with $error. Transitions is_ready to true, fires all callbacks registered via on_ready(), and wakes every fiber parked in await(), where the error is rethrown. Dies if the future is already ready.
is_ready( )
if ( $fut->is_ready ) { ... }
Returns true if the future has been fulfilled (either by a result or an error).
error( )
my $err = $fut->error;
Returns the error passed to set_error, or undef if the future succeeded or is not yet ready.
on_ready( sub ($future) { ... } )
$fut->on_ready( sub ($f) {
say "Finished with: " . ( $f->error // $f->result );
} );
Registers a callback to execute when the future resolves. The callback receives the future object as its sole argument. If the future is already ready, the callback executes immediately inline.
clear_result( )
$fut->clear_result;
Resets the future back to an unfulfilled state, clearing stored results, errors, callbacks, and waiters.
remove_waiter( $fid )
$fut->remove_waiter($fid);
Unregisters a fiber ID from the future's wake queue. Used by the scheduler when a wait is interrupted via a timeout or cancellation token.
Recipes
Bridging asynchronous callbacks to fibers
To integrate standard callback-based code with fibers, allocate a future and resolve it inside the callback:
sub fetch_async ($url) {
my $future = Acme::Parataxis::Future->new;
legacy_http_client()->get( $url, sub ( $status, $body ) {
if ($status == 200) { $future->set_result($body) }
else { $future->set_error("HTTP $status") }
} );
return $future;
}
async {
my $data = fetch_async('https://cpan.org')->await;
say "Downloaded: ${\length($data)} bytes";
};
Fan-out broadcast
Multiple fibers can await the same future; when fulfilled, all waiting fibers are resumed:
my $barrier = Acme::Parataxis::Future->new;
for my $id ( 1 .. 3 ) {
fiber {
$barrier->await;
say "Worker $id unblocked!";
};
}
fiber {
await_sleep(100);
$barrier->set_result(1); # wakes all 3 fibers
};
Behavior Notes
Exception preservation
Exceptions passed to
set_errorcan be plain strings or structured exception objects. They survive intact across theawaitboundary and rethrow in the awaiting fiber with their original class and properties preserved.Futures vs. Fibers
Every fiber spawned via
fiber { ... }orspawn { ... }implements the Future interface. You can pass a fiber directly towait_all,wait_any,await, or inspect its->resultonce complete.
SEE ALSO
Acme::Parataxis, Acme::Parataxis::Actor, Acme::Parataxis::Monitor
AUTHOR
Sanko Robinson https://github.com/sanko
LICENSE
Copyright (C) Sanko Robinson.
This library is free software; you can redistribute it and/or modify it under the terms found in the Artistic License 2.