summaryrefslogtreecommitdiff
path: root/lib/Thread/Task.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Thread/Task.pm')
-rw-r--r--lib/Thread/Task.pm115
1 files changed, 115 insertions, 0 deletions
diff --git a/lib/Thread/Task.pm b/lib/Thread/Task.pm
new file mode 100644
index 0000000..9966634
--- /dev/null
+++ b/lib/Thread/Task.pm
@@ -0,0 +1,115 @@
+use 5.008003;
+use MooseX::Declare;
+
+class Thread::Task {
+ use MooseX::Types::Moose qw(Object);
+ use Thread::Task::Types qw(Handle_T);
+
+ require Storable;
+
+ require Thread::Task::Role::Task;
+ require Thread::Task::Manager;
+ require Thread::Task::Exception::Finished;
+
+ our $VERSION='0.001';
+
+ has _owner_taskrev => (
+ isa => Int,
+ is => 'ro',
+ weak_ref => 1,
+ required => 0,
+ predicate => '_has_owner_taskrev',
+ );
+
+ has callback => (
+ isa => Str,
+ is => 'ro',
+ required => 0,
+ default => 'task_response',
+ );
+
+ has handle => (
+ isa => Handle_T,
+ is => 'rw',
+ required => 0,
+ predicate => 'running',
+ clearer => 'clear_handle',
+ );
+
+ around BUILDARGS (Class $class,@rest) {
+ my $params = $class->$orig(@rest);
+
+ if (exists $params->{owner}) {
+ $params->{_owner_taskrev} =
+ delete($params->{owner})->task_revision;
+ }
+ }
+
+ method BUILD() {
+ if ($self->_has_owner_taskrev) {
+ my $owner = $self->owner;
+ my $callback = $self->callback;
+ unless ($owner->can($callback)) {
+ die "Owner can't $callback";
+ }
+ }
+ }
+
+ method owner() {
+ Thread::Task::Role::Task->task_owner($self->_owner_taskrev);
+ }
+
+ method schedule(@args) {
+ Thread::Task::Manager->instance->schedule($self,@args);
+ }
+
+ method prepare() { return }
+
+ method run() {
+ if ($self->_has_owner_taskrev) {
+ $self->owner or die Thread::Task::Exception::Finished->new();
+ }
+
+ return;
+ }
+
+ method finish() {
+ if ($self->_has_owner_taskrev) {
+ my $owner = $self->owner
+ or die Thread::Task::Exception::Finished->new();
+
+ my $callback = $self->callback;
+
+ $owner->$callback($self);
+ }
+
+ return;
+ }
+
+ method as_string() {
+ Storable::nfreeze($self);
+ }
+
+ method from_string(Class $class: Str $serialization) {
+ my $self=Storable::nthaw($serialization);
+ my $self_class=$self->meta->name;
+ unless ($self_class eq $class) {
+ die "Deserialized as $self_class instead of $class";
+ }
+ return $self;
+ }
+
+ method _update(Task_T $new_task) {
+ if ($self->meta ne $new_task->meta) {
+ die "Can't update between different task classes";
+ }
+ for my $attr ($self->meta->get_all_attributes) {
+ $attr->set_value($self,
+ $attr->get_value($new_task)
+ );
+ }
+ return;
+ }
+}
+
+1;