use 5.008003;
use MooseX::Declare;
class Thread::Task {
use MooseX::Types::Moose qw(ClassName Str Int);
use Thread::Task::Types qw(Handle_T Task_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(ClassName $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(ClassName $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;