1Padre::Task(3)        User Contributed Perl Documentation       Padre::Task(3)
2
3
4

NAME

6       Padre::Task - Padre Task API 2.0
7

SYNOPSIS

9         # Fire a task that will communicate back to an owner object
10         My::Task->new(
11             owner      => $padre_role_task_object,
12             on_message => 'owner_message_method',
13             on_finish  => 'owner_finish_method',
14             my_param1  => 123,
15             my_param2  => 'abc',
16         )->schedule;
17
18
19
20         package My::Task;
21
22         sub new {
23             my $class = shift;
24             my $self  = $class->SUPER::new(@_);
25
26             # Check params and validate the task
27
28             return $self;
29         }
30
31         sub prepare {
32             my $self = shift;
33
34             # Run after scheduling immediately before serialised to a worker
35
36             return 0 if $self->my_last_second_abort_check;
37             return 1; # Continue and run
38         }
39
40         sub run {
41             my $self = shift;
42
43             # Called in child, do the work here
44
45             return 1;
46         }
47
48         sub finish {
49             my $self = shift;
50
51             # Called in parent after successful completion
52
53             return 1;
54         }
55
56         1;
57

DESCRIPTION

59       The Padre Task API implements support for background and parallel
60       execution of code in the Padre IDE, and is based on the CPAN Process
61       API.
62
63       A Task Class is a class that completely encapsulates a single unit of
64       work, describing not only the work to be done, but also how the unit of
65       work is created, how is serialised for transport, and any
66       initialisation or cleanup work needs to be done.
67
68       A Task is a single self-contained unit of work, and is implemented as a
69       single instance of a particular Task Class.
70
71   The lifecycle of a Task object
72       From the perspective of a task author, the execution of a task will
73       occur in four distinct phases.
74
75       1. Construction
76
77       The creation of a task is always done completely independantly of its
78       execution. Typically this is done via the "new" method, or something
79       that calls it.
80
81       This separate construction step allows validation of parameters in
82       advance, as well as allowing bulk task pre-generation and advanced task
83       management functionality such as prioritisation, queueing, throttling
84       and load-balancing of tasks.
85
86       2. Preparation
87
88       Once a task has been constructed, an arbitrarily long time may pass
89       before the code is actually run (if it is ever run at all).
90
91       If the actual execution of the task will result in certain work being
92       done in the parent thread, this work cannot be done in the constructor.
93       And once created as an object, no futher task code will be called until
94       the task is ready for execution.
95
96       To give the author a chance to allow for any problems that may occur as
97       a result of this delay, the Task API provides a preparation phase for
98       the task via the "prepare" method.
99
100       This preparation code is run in the parent thread once the task has
101       been prioritised, has a worker allocated to it, and has been
102       encapsulated in its Padre::TaskHandle, but before the object is
103       serialised for transport into the thread.
104
105       A task can use this preparation phase to detach from non-serialisable
106       resources in the object such as database handles, to copy any
107       interesting parent state late rather than early, or decide on a last-
108       second self-abort.
109
110       Once the preparation phase is completed the task will be serialised,
111       transported into assigned worker thread and then executed immediately.
112
113       Because it will execute in the parent thead, the rest of the Padre
114       instance is available for use if needed, but the preparation code
115       should run quickly and must not block.
116
117       3. Execution
118
119       The main phase of the task is where the CPU-intensive or blocking code
120       can be safely run. It is run inside a worker thread in the background,
121       without impacting on the performance of the parent thread.
122
123       However, the task execution phase must be entirely self-contained.
124
125       The worker threads not only do not have access to the Padre IDE
126       variable structure, but most Padre classes (including heavily used
127       modules such as Padre::Current) will not be loaded at all in the worker
128       thread.
129
130       Any output that needs to be transported back to the parent should be
131       stored in the object somewhere. When the cleanup phase is run, these
132       values will be available automatically in the parent.
133
134       4. Cleanup
135
136       When the execution phase of the task is completed, the task object will
137       be serialised for transport back up to the parent thread.
138
139       On arrival, the instance of the task in the parent will be gutted and
140       its contents replaced with the contents of the version arriving from
141       the child thread.
142
143       Once this is complete, the task object will fire a "finish" handler
144       allowing it to take action in the parent thread based on the work done
145       in the child.
146
147       This can include having the task contact any "owner" object that had
148       commissioned the task in the first place.
149

METHODS

151   new
152         My::Task->new(
153             owner      => $padre_role_task_object,
154             on_message => 'owner_message_method',
155             on_finish  => 'owner_finish_method',
156             my_param1  => 123,
157             my_param2  => 'abc',
158         );
159
160       The "new" method creates a new "task", a self-contained object that
161       represents a unit of work to be done in the background (although not
162       required to be done in the background).
163
164       In addition to defining a set of method for you to provide as the task
165       implementer, the base class also provides implements a "task ownership"
166       system in the base class that you may use for nearly no cost in terms
167       of code.
168
169       This task owner system will consume three paramters.
170
171       The optional "owner" parameter should be an object that inherits from
172       the role Padre::Role::Task. Message and finish events for this task
173       will be forwarded on to handlers on the owner, if they are defined.
174
175       The optional "on_message" parameter should be the name of a method that
176       can be called on the owner object, to be called when a message arrives
177       from the child object during its execution.
178
179       The required (if "owner" was provided) "on_finish" parameter should be
180       the name of a method that can be called on the owner object, to be
181       called when the task has completed and returns to the parent from the
182       child object.
183
184       When implementing your own task, you should always call the
185       "SUPER::new" method first, to ensure that integration with the task
186       owner system is done.
187
188       You can then check any other parameters, capture additional information
189       from the IDE, and validate that the task is correctly requested and
190       should go ahead.
191
192       The creation of a task object does NOT imply that it will be executed,
193       merely that the require for work to be done is validly formed. A task
194       object may never execute, or may only execute significantly later than
195       it was created.
196
197       Anything that the task needs to do once it is certain that the task
198       will be run should be done in the "prepare" method (see below).
199
200       Returns a new task object if the request is valid, or throws an
201       exception if the request is invalid.
202
203   owner
204       The "owner" method returns the owner object for the task, if one was
205       defined and the owner still exists and considers the answer for the
206       task to be relevant.
207
208       Returns "undef" if the task was not created with an owner.
209
210       Returns "undef" if the owner object has been destroyed since a task was
211       made.
212
213       Returns "undef" if the owner has abandoned this task since it was made.
214
215   on_message
216       The "on_message" accessor returns the name of the owner's message
217       handler method, if one was defined.
218
219   on_finish
220       The "on_finish" accessor returns the name of the owner's finish handler
221       method, if one was defined.
222
223   as_string
224       The "as_string" method is used to serialise the task into a string for
225       transmission between the parent and the child (in both directions).
226
227       By default your task will be serialised using Storable's "nfreeze"
228       method, which is suitable for transmission between threads or processes
229       running the same instance of Perl with the same module search path.
230
231       This should be sufficient in most situations.
232
233   from_string
234       The "from_string" method is used to deserialise the task from a string
235       after transmission between the parent and the child (in both
236       directions).
237
238       By default your task will be deserialised using Storable's "thaw"
239       method, which is suitable for transmission between threads or processes
240       running the same instance of Perl with the same module search path.
241
242       This should be sufficient in most situations.
243
244   schedule
245         $task->schedule;
246
247       The "schedule" method is used to trigger the sending of the task to a
248       worker for processing at whatever time the Task Manager deems it
249       appropriate.
250
251       This could be immediately, with the task sent before the call returns,
252       or it may be delayed indefinately or never run at all.
253
254       Returns true if the task was dispatched immediately.
255
256       Returns false if the task was queued for later dispatch.
257
258   prepare
259       The optional "prepare" method will be called by the task manager on
260       your task object while still in the parent thread, immediately before
261       being serialised to pass to the worker thread.
262
263       This method should be used to compensate for the potential time
264       difference between when "new" is oridinally called and when the task
265       will actually be run.
266
267       For example, a GUI element may indicate the need to run a background
268       task on the visible document but does not care that it is the literally
269       "current" document at the time the task was spawned.
270
271       By capturing the contents of the current document during "prepare"
272       rather than "new" the task object is able to apply the task to the most
273       up to date information at the time we are able to do the work, rather
274       than at the time we know we need to do the work.
275
276       The "prepare" method can take a relatively heavy parameter such as a
277       reference to a Wx element, and flatten it to the widget ID or contents
278       of the widget instead.
279
280       The "prepare" method also gives your task object a chance to determine
281       whether or not it is still necesary. In some situations the delay
282       between "new" and "prepare" may be long enough that the task is no
283       longer relevant, and so by the use of "prepare" you can indicate
284       execution should be aborted.
285
286       Returns true if the task is stil valid, and so the task should be
287       executed.
288
289       Returns false if the task is no longer valid, and the task should be
290       aborted.
291
292   run
293       The "run" method is called on the object in the worker thread
294       immediately after deserialisation. It is where the actual computations
295       and work for the task occurs.
296
297       In many situations the implementation of run is simple and procedural,
298       doing work based on input parameters stored on the object, blocking if
299       necesary, and storing the results of the computation on the object for
300       transmission back to the parent thread.
301
302       In more complex scenarios, you may wish to do a series of tasks or a
303       recursive set of tasks in a loop with a check on the "cancel" method
304       periodically to allow the aborting of the task if requested by the
305       parent.
306
307       In even more advanced situations, you may embed and launch an entire
308       event loop such as POE or AnyEvent inside the "run" method so that long
309       running or complex functionality can be run in the background.
310
311       Once inside of "run" your task is in complete control and the task
312       manager cannot interupt the execution of your code short of killing the
313       thread entirely. The standard "cancel" method to check for a request
314       from the parent to abort your task is cooperative and entirely
315       voluntary.
316
317       Returns true if the computation was completed successfully.
318
319       Returns false if the computation was not completed successfully, and so
320       the parent should not run any post-task logic.
321
322   finish
323       The "finish" method is called on the object in the parent thread once
324       it has been passed back up to the parent, if "run" completed
325       successfully.
326
327       It is responsible for cleaning up the task and taking any actions based
328       on the result of the computation.
329
330       If your task is fire-and-forget or void and you don't care about when
331       the task completes, you do not need to implement this method.
332
333       The default implementation of "finish" implements redirection to the
334       "on_finish" handler of the task owner object, if one has been defined.
335
336   cancel
337         sub run {
338             my $self = shift;
339
340             # Abort a long task if we are no longer wanted
341             foreach my $thing ( @{$self->{lots_of_stuff}} ) {
342                 return if $self->cancel;
343
344                 # Do something expensive
345             }
346
347             return 1;
348         }
349
350       The "cancel" method can be used in the worker thread by your task
351       during the execution of "run".
352

SEE ALSO

354       Padre, Process
355
357       Copyright 2008-2011 The Padre development team as listed in Padre.pm.
358
359       This program is free software; you can redistribute it and/or modify it
360       under the same terms as Perl 5 itself.
361
362       The full text of the license can be found in the LICENSE file included
363       with this module.
364
365
366
367perl v5.32.1                      2021-01-27                    Padre::Task(3)
Impressum