NAME

Hyperman::Future - a fast, native, Future-compatible async result

SYNOPSIS

use Hyperman::Future;

my $f = Hyperman::Future->new;
$f->then(sub { my $v = shift; ... });
$f->done(42);

my $all = Hyperman::Future->needs_all($f1, $f2);

# inside a running Hyperman worker, awaiting pumps the loop:
my @row = $db_future->get;

DESCRIPTION

An asynchronous result object with an API compatible with CPAN Future: done/fail/cancel, on_ready/on_done/on_fail/on_cancel, then/else/followed_by/transform, get/await, and the convergent combinators wait_all/wait_any/needs_all/needs_any.

on_cancel takes either a code reference, called with the future when it is cancelled, or another future, which is cancelled with it. Registering on a future that has already been cancelled runs the target at once; registering on one that completed normally drops it, because that future will never cancel.

The implementation is entirely XS over an array-slot object: creation, resolution, callback firing, chaining, and the combinators all run in C, with continuations as C closures trampolined through a fire queue - long then-chains run iteratively with bounded stack depth. Cancelling a future derived by then/followed_by/transform propagates the cancellation to its still-pending upstream.

get/await on a pending future inside a running Hyperman worker pump the worker's own event loop re-entrantly, servicing other connections meanwhile. Outside a Hyperman loop, an external loop may install $Hyperman::Future::AWAIT (a coderef receiving the future) to make awaiting work; without either, awaiting a pending future croaks.

as_cpan_future / from_future convert to and from CPAN Future objects when interop with isa('Future') code is needed. @ISA is deliberately not set to Future: inherited Future methods would operate on its hash-based internals, not this array-slot object.

ASYNC/AWAIT

This class implements the Future::AsyncAwait::Awaitable API, so one of these futures can be awaited directly:

use Future::AsyncAwait;

async sub handler {
    my $row = await $db_future;
    return [ 200, [], [ $row->{body} ] ];
}

Whatever it awaited, an async sub returns a CPAN Future by default. Naming this class at import makes it return one of these instead, which is what a Hyperman worker parks a request on:

use Future::AsyncAwait future_class => 'Hyperman::Future';

Cancelling the future an async sub returned cancels whichever future it is suspended on. The AWAIT_* methods are that protocol; call the documented names above rather than those.

AUTHOR

LNATION <email@lnation.org>

LICENSE AND COPYRIGHT

This software is Copyright (c) 2026 by LNATION. This is free software, licensed under the Artistic License 2.0.