Commit | Line | Data |
20038dd8 |
1 | package App::Clifton::Task; |
2 | |
3 | use Log::Contextual qw(:log); |
4 | use Async::MergePoint; |
5 | use Moo; |
6 | |
7 | extends 'App::Clifton::Component'; |
8 | |
9 | has on_finished => (is => 'rw'); |
10 | |
11 | has name => (is => 'ro', required => 1); |
12 | |
13 | has body => (is => 'ro', required => 1); |
14 | |
327a4b1a |
15 | has guard => (is => 'ro', predicate => 'has_guard'); |
16 | |
17 | has args => (is => 'ro', required => 1); |
18 | |
20038dd8 |
19 | has dependencies => (is => 'ro', default => sub { {} }); |
20 | |
21 | has merge_point => (is => 'lazy'); |
22 | |
23 | sub _build_merge_point { Async::MergePoint->new } |
24 | |
25 | sub BUILD { |
26 | my ($self) = @_; |
327a4b1a |
27 | if (my $cb = $self->args->{on_finished}) { |
28 | $self->on_finished($cb); |
29 | } |
20038dd8 |
30 | my $deps = $self->dependencies; |
31 | if (my @needs = keys %$deps) { |
32 | my $mp = $self->merge_point; |
33 | $mp->needs(@needs); |
34 | foreach my $key (@needs) { |
35 | $deps->{$key}->on_finished(sub { $mp->done($key => $_[0]) }); |
36 | } |
37 | $mp->close(on_finished => $self->_capture_weakself('_schedule_body')); |
38 | } else { |
39 | $self->_schedule_body; |
40 | } |
41 | } |
42 | |
43 | sub _schedule_body { |
44 | my ($self, %args) = @_; |
45 | my $fire_body = $self->_capture_weakself('_fire_body'); |
46 | $args{on_finished} = $self->_finished_callback; |
327a4b1a |
47 | %args = (%{$self->args}, %args); |
20038dd8 |
48 | $self->_schedule(sub { $fire_body->(\%args); }); |
49 | } |
50 | |
51 | sub _fire_body { |
52 | my $self = shift; |
327a4b1a |
53 | if ($self->has_guard and my ($result) = $self->guard->(@_)) { |
54 | $_[0]->{on_finished}($result); |
55 | } else { |
56 | $self->body->(@_); |
57 | } |
20038dd8 |
58 | } |
59 | |
60 | sub _finished_callback { |
61 | my ($self) = @_; |
62 | $self->_capture_weakself('_schedule_finished'); |
63 | } |
64 | |
65 | sub _schedule_finished { |
66 | my ($self, @args) = @_; |
67 | if (my $on_finished = $self->on_finished) { |
68 | $self->_schedule(sub { $on_finished->(@args) }); |
69 | } |
70 | $self->parent->remove_child($self); |
71 | #$self->$::Dwarn; |
72 | #warn Devel::FindRef::track $self; |
73 | } |
74 | |
75 | 1; |