Acme-Parataxis

 view release on metacpan or  search on metacpan

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

                $n->spawn( sub { await_sleep(10_000) } );
            } );
        };

        if ( my $err = $@ ) {
            if ( ref $err && $err->isa('Acme::Parataxis::Error::Nursery') ) {
                say "Root cause: " . $err->primary;    # "Database connection lost"
                say "Total child errors: " . scalar( $err->failures ); # 2 (database error + cancelled sleep)
            }
        }
    };

=head1 Recipes

=head2 Concurrent scatter-gather

To collect data from children, write into variables in the parent's lexical scope:

    my ( $orders, $inventory, $shipping );

    nursery( sub ($n) {
        $n->spawn( sub { $orders    = load_orders($id) } );
        $n->spawn( sub { $inventory = check_stock($id) } );
        $n->spawn( sub { $shipping  = calc_rates($id)  } );
    } );

    # All three lookups are complete and successful here.

=head2 Setting a deadline on the entire nursery

Pass the nursery's token to L<with_timeout|Acme::Parataxis/with_timeout>:

    use Acme::Parataxis qw[async nursery with_timeout await_sleep];

    async {
        eval {
            nursery( sub ($n) {
                $n->spawn( sub { await_sleep(5000) } );
                $n->spawn( sub { await_sleep(5000) } );

                # If 500ms elapses, the token cancels and aborts both children:
                with_timeout( 500, $n->token, sub { await_sleep(10_000) } );
            } );
        };
        warn "Nursery timed out: $@" if $@;
    };

=head1 Behavior Notes

=over

=item * Block returns do not short-circuit children

The block passed to C<nursery()> cannot return early to bypass pending children. The nursery joins I<every> child
spawned via C<< $n->spawn >> before returning. The nursery's return value is the return value of the enclosed block,
delivered only when all children have succeeded.

=item * Fail-fast vs. best-effort

A nursery enforces all-or-nothing execution. The moment one child fails, all surviving siblings are cancelled. If you
need independent background tasks where failures do not cascade, use unmanaged C<fiber { ... }> instances combined with
L<Acme::Parataxis::Monitor> instead.

=item * Parent exceptions take priority

If the parent block itself throws an exception before spawning finishes, all currently enrolled children are
immediately cancelled and drained, and the parent's own exception is rethrown verbatim (not wrapped in an
C<Error::Nursery>).

=item * Nested nurseries are isolated

Nesting a C<nursery> inside another forms an independent hierarchy. A failure in an inner nursery cancels only its own
children; if the inner nursery's error is caught with an C<eval>, the outer nursery continues uninterrupted.

=back

=head1 SEE ALSO

L<Acme::Parataxis>, L<Acme::Parataxis::CancellationToken>, L<Acme::Parataxis::Error>, L<Acme::Parataxis::Monitor>

=head1 AUTHOR

Sanko Robinson L<https://github.com/sanko>

=head1 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.

=cut



( run in 0.567 second using v1.01-cache-2.11-cpan-f1796dc4e6b )