summaryrefslogtreecommitdiff
path: root/lib/Thread/Task.pm
blob: 5567805deefec902e9f7b42d2e22d395d5e8c6e0 (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
116
117
118
use 5.008003;
use MooseX::Declare;
 
class Thread::Task {
    use MooseX::Types::Moose qw(ClassName Str Int HashRef);
    use Thread::Task::Types qw(Handle_T Task_T TaskRev_T);
    use Moose::Util::TypeConstraints;
 
    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,
        init_arg => 'owner',
        predicate => '_has_owner_taskrev',
    );
 
    coerce TaskRev_T, from Task_T,
        via {
            $_->task_revision;
        };
 
    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',
    );
 
    method BUILD(HashRef $params) {
        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 $new_self=Storable::thaw($serialization);
        my $self_class=$new_self->meta->name;
        unless ($self_class eq $class) {
            die "Deserialized as $self_class instead of $class";
        }
        return $new_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) {
            if ($attr->has_value($new_task)) {
                $attr->set_value($self,
                                 $attr->get_value($new_task)
                             );
            }
            else {
                $attr->clear_value($self);
            }
        }
        return;
    }
}
 
1;