summaryrefslogtreecommitdiff
path: root/lib/Thread/Task.pm
blob: 99666349982b1bd2ebb29ab861652e5834278422 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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;