216e3c3b1b5cc01da96ddc5ac7fb84ef99faa97c
[scpubgit/Clifton.git] / lib / App / Clifton / Task.pm
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
15 has dependencies => (is => 'ro', default => sub { {} });
16
17 has merge_point => (is => 'lazy');
18
19 sub _build_merge_point { Async::MergePoint->new }
20
21 sub BUILD {
22   my ($self) = @_;
23   my $deps = $self->dependencies;
24   if (my @needs = keys %$deps) {
25     my $mp = $self->merge_point;
26     $mp->needs(@needs);
27     foreach my $key (@needs) {
28       $deps->{$key}->on_finished(sub { $mp->done($key => $_[0]) });
29     }
30     $mp->close(on_finished => $self->_capture_weakself('_schedule_body'));
31   } else {
32     $self->_schedule_body;
33   }
34 }
35
36 sub _schedule_body {
37   my ($self, %args) = @_;
38   my $fire_body = $self->_capture_weakself('_fire_body');
39   $args{on_finished} = $self->_finished_callback;
40   $self->_schedule(sub { $fire_body->(\%args); });
41 }
42
43 sub _fire_body {
44   my $self = shift;
45   $self->body->(@_);
46 }
47
48 sub _finished_callback {
49   my ($self) = @_;
50   $self->_capture_weakself('_schedule_finished');
51 }
52
53 sub _schedule_finished {
54   my ($self, @args) = @_;
55   if (my $on_finished = $self->on_finished) {
56     $self->_schedule(sub { $on_finished->(@args) });
57   }
58   $self->parent->remove_child($self);
59 #$self->$::Dwarn;
60 #warn Devel::FindRef::track $self;
61 }
62
63 1;