The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Async::Selector::Aggregator - aggregator of watchers and other aggregators

VERSION

1.02

SYNOPSIS

    use Async::Selector;
    use Async::Selector::Aggregator;
    
    ## Setup resources with 3 selectors, each of which registers 'resource'
    my %resources = (
        a => { val => 0, selector => Async::Selector->new },
        b => { val => 0, selector => Async::Selector->new },
        c => { val => 0, selector => Async::Selector->new },
    );
    foreach my $res (values %resources) {
        $res->{selector}->register(resource => sub {
            my ($threshold) = @_;
            return $res->{val} >= $threshold ? $res->{val} : undef;
        });
    }
    
    ## Aggregate 3 selectors into one. Resource names are now ('a', 'b', 'c')
    sub aggregate_watch {
        my $callback = pop;
        my %watch_spec = @_;
        my $aggregator = Async::Selector::Aggregator->new();
        foreach my $key (keys %watch_spec) {
            my $watcher = $resources{$key}{selector}->watch(
                resource => $watch_spec{$key}, sub {
                    my ($w, %res) = @_;
                    $callback->($aggregator, $key => $res{resource});
                }
            );
            $aggregator->add($watcher);
            last if !$aggregator->active;
        }
        return $aggregator;
    }
    
    ## Treat 3 selectors like a single selector almost transparently.
    ## $w and $watcher are actually an Async::Selector::Aggregator.
    my $watcher = aggregate_watch(a => 3, b => 0, sub {
        my ($w, %res) = @_;
        handle_a($res{a}) if exists $res{a};
        handle_b($res{b}) if exists $res{b};
        $w->cancel;
    });
    
    ## In this case, the callback is called immediately and $w->cancel is called.
    
    $watcher->active;  ## => false

DESCRIPTION

Async::Selector::Aggregator is an object that keeps Async::Selector::Watcher objects and/or other aggregator objects and treats them as a single watcher. Using Async::Selector::Aggregator, you can ensure that a certain set of watchers are always cancelled at the same time. This is useful when you use multiple Async::Selectors and treat them as a single selector.

Watchers and aggregators kept in an Async::Selector::Aggregator are in one of the two states; they are all active or they are all inactive. No intermediate state is possible unless you call cancel() method on individual watchers. You should not cancel individual watchers once you aggregate them into an Async::Selector::Aggregator object.

CLASS METHODS

$aggregator = Async::Selector::Aggregator->new()

Creates a new Async::Selector::Aggregator object. It takes no argument.

A newly created aggregator is active.

OBJECT METHODS

$aggregator->add($watcher)

Adds the given $watcher to the $aggregator. The $watcher may be an Async::Selector::Watcher object or an Async::Selector::Aggregator object.

If $aggregator is active and $watcher is inactive, $aggregator->cancel() is automatically called. If $aggregator is inactive and $watcher is active, $watcher->cancel() is automatically called. This is because all watchers in the $aggregator must share the same state.

If $watcher is the same instance as $aggregator, it croaks.

@watchers = $aggregator->watchers()

Returns the list of all watchers kept in the $aggregator.

$is_active = $aggregator->active()

Returns true if the $aggregator is active. Returns false otherwise.

$aggregator->cancel()

Cancels the $aggregator, that is, changes its state into inactive. This method also cancels all watchers kept in the $aggregator.

AUTHOR

Toshio Ito <toshioito at cpan.org>