sketch out some service code
[scpubgit/Clifton.git] / lib / App / Clifton / Task.pm
diff --git a/lib/App/Clifton/Task.pm b/lib/App/Clifton/Task.pm
new file mode 100644 (file)
index 0000000..216e3c3
--- /dev/null
@@ -0,0 +1,63 @@
+package App::Clifton::Task;
+
+use Log::Contextual qw(:log);
+use Async::MergePoint;
+use Moo;
+
+extends 'App::Clifton::Component';
+
+has on_finished => (is => 'rw');
+
+has name => (is => 'ro', required => 1);
+
+has body => (is => 'ro', required => 1);
+
+has dependencies => (is => 'ro', default => sub { {} });
+
+has merge_point => (is => 'lazy');
+
+sub _build_merge_point { Async::MergePoint->new }
+
+sub BUILD {
+  my ($self) = @_;
+  my $deps = $self->dependencies;
+  if (my @needs = keys %$deps) {
+    my $mp = $self->merge_point;
+    $mp->needs(@needs);
+    foreach my $key (@needs) {
+      $deps->{$key}->on_finished(sub { $mp->done($key => $_[0]) });
+    }
+    $mp->close(on_finished => $self->_capture_weakself('_schedule_body'));
+  } else {
+    $self->_schedule_body;
+  }
+}
+
+sub _schedule_body {
+  my ($self, %args) = @_;
+  my $fire_body = $self->_capture_weakself('_fire_body');
+  $args{on_finished} = $self->_finished_callback;
+  $self->_schedule(sub { $fire_body->(\%args); });
+}
+
+sub _fire_body {
+  my $self = shift;
+  $self->body->(@_);
+}
+
+sub _finished_callback {
+  my ($self) = @_;
+  $self->_capture_weakself('_schedule_finished');
+}
+
+sub _schedule_finished {
+  my ($self, @args) = @_;
+  if (my $on_finished = $self->on_finished) {
+    $self->_schedule(sub { $on_finished->(@args) });
+  }
+  $self->parent->remove_child($self);
+#$self->$::Dwarn;
+#warn Devel::FindRef::track $self;
+}
+
+1;