Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 459 lines (385 sloc) 16.586 kB
adb0700 @ztane python 3 support (python 2 not yet tested)
ztane authored
1 # -*- coding: utf-8 -*-
2 from __future__ import division
a7e4ffc Initial import.
knipknap authored
3 # Copyright (C) 2007 Samuel Abels
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
2fbf57e @knipknap minor api doc fixes.
authored
9 #
a7e4ffc Initial import.
knipknap authored
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
2fbf57e @knipknap minor api doc fixes.
authored
14 #
a7e4ffc Initial import.
knipknap authored
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
fe31b70 @ziadsawalha add some logging.
ziadsawalha authored
18 import logging
19
74d209c @knipknap get rid of the SpiffSignal dependency.
authored
20 from SpiffWorkflow.util.event import Event
21 from SpiffWorkflow.Task import Task
a3d894c @knipknap rename SpiffWorkflow.Exception to SpiffWorkflow.exceptions.
authored
22 from SpiffWorkflow.exceptions import WorkflowException
fe31b70 @ziadsawalha add some logging.
ziadsawalha authored
23
c130460 @ziadsawalha minor cleanups.
ziadsawalha authored
24
fe31b70 @ziadsawalha add some logging.
ziadsawalha authored
25 LOG = logging.getLogger(__name__)
a7e4ffc Initial import.
knipknap authored
26
c130460 @ziadsawalha minor cleanups.
ziadsawalha authored
27
74d209c @knipknap get rid of the SpiffSignal dependency.
authored
28 class TaskSpec(object):
a7e4ffc Initial import.
knipknap authored
29 """
0dfeb17 Rename Tasks.Task to Tasks.TaskSpec, and add Tasks.Simple.
knipknap authored
30 This class implements an abstract base type for all tasks.
a7e4ffc Initial import.
knipknap authored
31
32 Tasks provide the following signals:
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
33 - **entered**: called when the state changes to READY or WAITING, at a
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
34 time where spec data is not yet initialized.
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
35 - **reached**: called when the state changes to READY or WAITING, at a
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
36 time where spec data is already initialized using data_assign
a7e4ffc Initial import.
knipknap authored
37 and pre-assign.
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
38 - **ready**: called when the state changes to READY, at a time where
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
39 spec data is already initialized using data_assign and
a7e4ffc Initial import.
knipknap authored
40 pre-assign.
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
41 - **completed**: called when the state changes to COMPLETED, at a time
a7e4ffc Initial import.
knipknap authored
42 before the post-assign variables are assigned.
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
43 - **cancelled**: called when the state changes to CANCELLED, at a time
a7e4ffc Initial import.
knipknap authored
44 before the post-assign variables are assigned.
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
45 - **finished**: called when the state changes to COMPLETED or CANCELLED,
324fe05 @knipknap implement 'cancelled' and 'finished' events for TaskSpec.
authored
46 at the last possible time after the post-assign variables are
47 assigned and mutexes are released.
f75709c @ziadsawalha Incorporated Samuel's comments into documentation
ziadsawalha authored
48
c130460 @ziadsawalha minor cleanups.
ziadsawalha authored
49 Event sequence is: entered -> reached -> ready -> completed -> finished
50 (cancelled may happen at any time)
51
52 The only events where implementing something other than state tracking
f75709c @ziadsawalha Incorporated Samuel's comments into documentation
ziadsawalha authored
53 may be useful are the following:
c130460 @ziadsawalha minor cleanups.
ziadsawalha authored
54 - Reached: You could mess with the pre-assign variables here, for
55 example. Other then that, there is probably no need in a real
56 application.
57 - Ready: This is where a task could implement custom code, for example
58 for triggering an external system. This is also the only event where a
59 return value has a meaning (returning non-True will mean that the
60 post-assign procedure is skipped.)
a7e4ffc Initial import.
knipknap authored
61 """
62
63 def __init__(self, parent, name, **kwargs):
64 """
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
65 Constructor.
a7e4ffc Initial import.
knipknap authored
66
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
67 The difference between the assignment of a data value using
68 the data argument versus pre_assign and post_assign is that
69 changes made using data are task-local, i.e. they are
a7e4ffc Initial import.
knipknap authored
70 not visible to other tasks.
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
71 Similarly, "defines" are spec data fields that, once defined, can
72 no longer be modified.
a7e4ffc Initial import.
knipknap authored
73
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
74 :type parent: L{SpiffWorkflow.specs.WorkflowSpec}
75 :param parent: A reference to the parent (usually a workflow).
76 :type name: string
77 :param name: A name for the task.
78 :type lock: list(str)
79 :param lock: A list of mutex names. The mutex is acquired
80 on entry of execute() and released on leave of
81 execute().
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
82 :type data: dict((str, object))
83 :param data: name/value pairs
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
84 :type defines: dict((str, object))
85 :param defines: name/value pairs
86 :type pre_assign: list((str, object))
87 :param pre_assign: a list of name/value pairs
88 :type post_assign: list((str, object))
89 :param post_assign: a list of name/value pairs
a7e4ffc Initial import.
knipknap authored
90 """
91 assert parent is not None
92 assert name is not None
93 self._parent = parent
94 self.id = None
95 self.name = str(name)
96 self.description = kwargs.get('description', '')
97 self.inputs = []
98 self.outputs = []
99 self.manual = False
100 self.internal = False # Only for easing debugging.
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
101 self.data = kwargs.get('data', {})
a7e4ffc Initial import.
knipknap authored
102 self.defines = kwargs.get('defines', {})
103 self.pre_assign = kwargs.get('pre_assign', [])
104 self.post_assign = kwargs.get('post_assign', [])
105 self.locks = kwargs.get('lock', [])
106 self.lookahead = 2 # Maximum number of MAYBE predictions.
74d209c @knipknap get rid of the SpiffSignal dependency.
authored
107
108 # Events.
109 self.entered_event = Event()
110 self.reached_event = Event()
111 self.ready_event = Event()
112 self.completed_event = Event()
324fe05 @knipknap implement 'cancelled' and 'finished' events for TaskSpec.
authored
113 self.cancelled_event = Event()
114 self.finished_event = Event()
74d209c @knipknap get rid of the SpiffSignal dependency.
authored
115
a7e4ffc Initial import.
knipknap authored
116 self._parent._add_notify(self)
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
117 self.data.update(self.defines)
a7e4ffc Initial import.
knipknap authored
118 assert self.id is not None
119
b385af1 More variable renaming magic.
knipknap authored
120 def _connect_notify(self, taskspec):
a7e4ffc Initial import.
knipknap authored
121 """
122 Called by the previous task to let us know that it exists.
123
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
124 :type taskspec: TaskSpec
125 :param taskspec: The task by which this method is executed.
a7e4ffc Initial import.
knipknap authored
126 """
b385af1 More variable renaming magic.
knipknap authored
127 self.inputs.append(taskspec)
a7e4ffc Initial import.
knipknap authored
128
e9750cb @ziadsawalha Add TaskSpec.ancestors() Call
ziadsawalha authored
129 def ancestors(self):
130 """Returns list of ancestor task specs based on inputs"""
131 results = []
132
133 def recursive_find_ancestors(task, stack):
134 for input in task.inputs:
135 if input not in stack:
136 stack.append(input)
137 recursive_find_ancestors(input, stack)
138 recursive_find_ancestors(self, results)
139
140 return results
141
b385af1 More variable renaming magic.
knipknap authored
142 def _get_activated_tasks(self, my_task, destination):
a7e4ffc Initial import.
knipknap authored
143 """
2fbf57e @knipknap minor api doc fixes.
authored
144 Returns the list of tasks that were activated in the previous
b385af1 More variable renaming magic.
knipknap authored
145 call of execute(). Only returns tasks that point towards the
5fd8e39 @knipknap terminology fix: replace references to the name 'node' by 'task'.
authored
146 destination task, i.e. those which have destination as a
a7e4ffc Initial import.
knipknap authored
147 descendant.
148
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
149 :type my_task: Task
150 :param my_task: The associated task in the task tree.
151 :type destination: Task
152 :param destination: The destination task.
a7e4ffc Initial import.
knipknap authored
153 """
b385af1 More variable renaming magic.
knipknap authored
154 return my_task.children
a7e4ffc Initial import.
knipknap authored
155
b385af1 More variable renaming magic.
knipknap authored
156 def _get_activated_threads(self, my_task):
a7e4ffc Initial import.
knipknap authored
157 """
2fbf57e @knipknap minor api doc fixes.
authored
158 Returns the list of threads that were activated in the previous
a7e4ffc Initial import.
knipknap authored
159 call of execute().
160
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
161 :type my_task: Task
162 :param my_task: The associated task in the task tree.
a7e4ffc Initial import.
knipknap authored
163 """
b385af1 More variable renaming magic.
knipknap authored
164 return my_task.children
a7e4ffc Initial import.
knipknap authored
165
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
166 def set_data(self, **kwargs):
a7e4ffc Initial import.
knipknap authored
167 """
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
168 Defines the given data field(s) using the given name/value pairs.
a7e4ffc Initial import.
knipknap authored
169 """
170 for key in kwargs:
caa845d @ziadsawalha PEP8 cleanups.
ziadsawalha authored
171 if key in self.defines:
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
172 msg = "Spec data %s can not be modified" % key
265a442 @ziadsawalha Fix Incorrect Duplicate Task Handling
ziadsawalha authored
173 raise WorkflowException(self, msg)
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
174 self.data.update(kwargs)
a7e4ffc Initial import.
knipknap authored
175
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
176 def get_data(self, name, default=None):
a7e4ffc Initial import.
knipknap authored
177 """
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
178 Returns the value of the data field with the given name, or the
179 given default value if the data was not defined.
a7e4ffc Initial import.
knipknap authored
180
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
181 :type name: string
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
182 :param name: The name of the data field.
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
183 :type default: string
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
184 :param default: Returned if the data field is not defined.
a7e4ffc Initial import.
knipknap authored
185 """
b1c19a0 @knipknap rename TaskSpec.properties to TaskSpec.data.
authored
186 return self.data.get(name, default)
a7e4ffc Initial import.
knipknap authored
187
b385af1 More variable renaming magic.
knipknap authored
188 def connect(self, taskspec):
a7e4ffc Initial import.
knipknap authored
189 """
190 Connect the *following* task to this one. In other words, the
191 given task is added as an output task.
192
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
193 :type taskspec: TaskSpec
194 :param taskspec: The new output task.
a7e4ffc Initial import.
knipknap authored
195 """
b385af1 More variable renaming magic.
knipknap authored
196 self.outputs.append(taskspec)
197 taskspec._connect_notify(self)
a7e4ffc Initial import.
knipknap authored
198
85da6db @ziadsawalha Add 'follow' which IMHO is clearer than 'connect'
ziadsawalha authored
199 def follow(self, taskspec):
200 """
201 Make this task follow the provided one. In other words, this task is
202 added to the given task outputs.
203
204 This is an alias to connect, just easier to understand when reading
205 code - ex: my_task.follow(the_other_task)
206 Adding it after being confused by .connect one times too many!
207
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
208 :type taskspec: TaskSpec
209 :param taskspec: The task to follow.
85da6db @ziadsawalha Add 'follow' which IMHO is clearer than 'connect'
ziadsawalha authored
210 """
211 taskspec.connect(self)
212
a7e4ffc Initial import.
knipknap authored
213 def test(self):
214 """
215 Checks whether all required attributes are set. Throws an exception
216 if an error was detected.
217 """
218 if self.id is None:
5c846b5 @knipknap fix broken error handling in TaskSpec.test().
authored
219 raise WorkflowException(self, 'TaskSpec is not yet instanciated.')
a7e4ffc Initial import.
knipknap authored
220 if len(self.inputs) < 1:
5c846b5 @knipknap fix broken error handling in TaskSpec.test().
authored
221 raise WorkflowException(self, 'No input task connected.')
a7e4ffc Initial import.
knipknap authored
222
caa845d @ziadsawalha PEP8 cleanups.
ziadsawalha authored
223 def _predict(self, my_task, seen=None, looked_ahead=0):
a7e4ffc Initial import.
knipknap authored
224 """
ed13665 @knipknap minor refactoring in TaskSpec._predict().
authored
225 Updates the branch such that all possible future routes are added.
a7e4ffc Initial import.
knipknap authored
226
ed13665 @knipknap minor refactoring in TaskSpec._predict().
authored
227 Should NOT be overwritten! Instead, overwrite _predict_hook().
d901dc6 Improved API documentation, fixed documentation generator.
knipknap authored
228
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
229 :type my_task: Task
230 :param my_task: The associated task in the task tree.
231 :type seen: list[taskspec]
232 :param seen: A list of already visited tasks.
233 :type looked_ahead: integer
234 :param looked_ahead: The depth of the predicted path so far.
a7e4ffc Initial import.
knipknap authored
235 """
1a59a85 @knipknap ignore return value of TaskSpec._update_state_hook().
authored
236 if my_task._is_finished():
237 return
a7e4ffc Initial import.
knipknap authored
238 if seen is None:
239 seen = []
240 elif self in seen:
241 return
b385af1 More variable renaming magic.
knipknap authored
242 if not my_task._is_finished():
243 self._predict_hook(my_task)
ed13665 @knipknap minor refactoring in TaskSpec._predict().
authored
244 if not my_task._is_definite():
245 if looked_ahead + 1 >= self.lookahead:
246 return
247 seen.append(self)
5fd8e39 @knipknap terminology fix: replace references to the name 'node' by 'task'.
authored
248 for child in my_task.children:
ed13665 @knipknap minor refactoring in TaskSpec._predict().
authored
249 child.task_spec._predict(child, seen[:], looked_ahead + 1)
a7e4ffc Initial import.
knipknap authored
250
b385af1 More variable renaming magic.
knipknap authored
251 def _predict_hook(self, my_task):
3d7b77c @knipknap replace Task._update_children by Task._sync_children() that uses much…
authored
252 # If the task's status is not predicted, we default to FUTURE
253 # for all it's outputs.
254 # Otherwise, copy my own state to the children.
b385af1 More variable renaming magic.
knipknap authored
255 if my_task._is_definite():
9d6e535 @knipknap minor cleanup.
authored
256 best_state = Task.FUTURE
a7e4ffc Initial import.
knipknap authored
257 else:
9d6e535 @knipknap minor cleanup.
authored
258 best_state = my_task.state
3d7b77c @knipknap replace Task._update_children by Task._sync_children() that uses much…
authored
259
9d6e535 @knipknap minor cleanup.
authored
260 my_task._sync_children(self.outputs, best_state)
3d7b77c @knipknap replace Task._update_children by Task._sync_children() that uses much…
authored
261 for child in my_task.children:
262 if not child._is_definite():
9d6e535 @knipknap minor cleanup.
authored
263 child._set_state(best_state)
a7e4ffc Initial import.
knipknap authored
264
b385af1 More variable renaming magic.
knipknap authored
265 def _update_state(self, my_task):
e39ea6a @knipknap minor refactoring and more docs for TaskSpec._update_state*().
authored
266 """
267 Called whenever any event happens that may affect the
268 state of this task in the workflow. For example, if a predecessor
269 completes it makes sure to call this method so we can react.
270 """
7e5e528 @knipknap rename Task.attributes and Workflow.attributes to .data. fixes #16.
authored
271 my_task._inherit_data()
1a59a85 @knipknap ignore return value of TaskSpec._update_state_hook().
authored
272 self._update_state_hook(my_task)
a7e4ffc Initial import.
knipknap authored
273
b385af1 More variable renaming magic.
knipknap authored
274 def _update_state_hook(self, my_task):
e39ea6a @knipknap minor refactoring and more docs for TaskSpec._update_state*().
authored
275 """
276 Typically this method should perform the following actions::
277
278 - Update the state of the corresponding task.
279 - Update the predictions for its successors.
280
281 Returning non-False will cause the task to go into READY.
282 Returning any other value will cause no action.
283 """
284 if my_task._is_predicted():
b385af1 More variable renaming magic.
knipknap authored
285 self._predict(my_task)
fe31b70 @ziadsawalha add some logging.
ziadsawalha authored
286 LOG.debug("'%s'._update_state_hook says parent (%s, state=%s) "
287 "is_finished=%s" % (self.name, my_task.parent.get_name(),
288 my_task.parent.get_state_name(),
289 my_task.parent._is_finished()))
1a59a85 @knipknap ignore return value of TaskSpec._update_state_hook().
authored
290 if not my_task.parent._is_finished():
291 return
292 self.entered_event.emit(my_task.workflow, my_task)
293 my_task._ready()
a7e4ffc Initial import.
knipknap authored
294
b385af1 More variable renaming magic.
knipknap authored
295 def _on_ready(self, my_task):
a7e4ffc Initial import.
knipknap authored
296 """
297 Return True on success, False otherwise.
298
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
299 :type my_task: Task
300 :param my_task: The associated task in the task tree.
a7e4ffc Initial import.
knipknap authored
301 """
b385af1 More variable renaming magic.
knipknap authored
302 assert my_task is not None
a7e4ffc Initial import.
knipknap authored
303 self.test()
304
305 # Acquire locks, if any.
306 for lock in self.locks:
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
307 mutex = my_task.workflow._get_mutex(lock)
a7e4ffc Initial import.
knipknap authored
308 if not mutex.testandset():
702e960 @knipknap ignore return value of TaskSpec._on_ready().
authored
309 return
a7e4ffc Initial import.
knipknap authored
310
311 # Assign variables, if so requested.
312 for assignment in self.pre_assign:
b385af1 More variable renaming magic.
knipknap authored
313 assignment.assign(my_task, my_task)
a7e4ffc Initial import.
knipknap authored
314
315 # Run task-specific code.
cfaa78f @knipknap ignore return value of TaskSpec._on_ready_before().
authored
316 self._on_ready_before_hook(my_task)
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
317 self.reached_event.emit(my_task.workflow, my_task)
ba93fb0 @knipknap ignore return value of TaskSpec._on_ready_hook().
authored
318 self._on_ready_hook(my_task)
a7e4ffc Initial import.
knipknap authored
319
320 # Run user code, if any.
702e960 @knipknap ignore return value of TaskSpec._on_ready().
authored
321 if self.ready_event.emit(my_task.workflow, my_task):
a7e4ffc Initial import.
knipknap authored
322 # Assign variables, if so requested.
323 for assignment in self.post_assign:
b385af1 More variable renaming magic.
knipknap authored
324 assignment.assign(my_task, my_task)
a7e4ffc Initial import.
knipknap authored
325
326 # Release locks, if any.
327 for lock in self.locks:
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
328 mutex = my_task.workflow._get_mutex(lock)
a7e4ffc Initial import.
knipknap authored
329 mutex.unlock()
330
324fe05 @knipknap implement 'cancelled' and 'finished' events for TaskSpec.
authored
331 self.finished_event.emit(my_task.workflow, my_task)
a7e4ffc Initial import.
knipknap authored
332
b385af1 More variable renaming magic.
knipknap authored
333 def _on_ready_before_hook(self, my_task):
a7e4ffc Initial import.
knipknap authored
334 """
335 A hook into _on_ready() that does the task specific work.
336
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
337 :type my_task: Task
338 :param my_task: The associated task in the task tree.
a7e4ffc Initial import.
knipknap authored
339 """
cfaa78f @knipknap ignore return value of TaskSpec._on_ready_before().
authored
340 pass
a7e4ffc Initial import.
knipknap authored
341
b385af1 More variable renaming magic.
knipknap authored
342 def _on_ready_hook(self, my_task):
a7e4ffc Initial import.
knipknap authored
343 """
344 A hook into _on_ready() that does the task specific work.
345
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
346 :type my_task: Task
347 :param my_task: The associated task in the task tree.
a7e4ffc Initial import.
knipknap authored
348 """
ba93fb0 @knipknap ignore return value of TaskSpec._on_ready_hook().
authored
349 pass
a7e4ffc Initial import.
knipknap authored
350
b385af1 More variable renaming magic.
knipknap authored
351 def _on_cancel(self, my_task):
a7e4ffc Initial import.
knipknap authored
352 """
353 May be called by another task to cancel the operation before it was
354 completed.
355
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
356 :type my_task: Task
357 :param my_task: The associated task in the task tree.
a7e4ffc Initial import.
knipknap authored
358 """
324fe05 @knipknap implement 'cancelled' and 'finished' events for TaskSpec.
authored
359 self.cancelled_event.emit(my_task.workflow, my_task)
a7e4ffc Initial import.
knipknap authored
360
b385af1 More variable renaming magic.
knipknap authored
361 def _on_trigger(self, my_task):
a7e4ffc Initial import.
knipknap authored
362 """
363 May be called by another task to trigger a task-specific
364 event.
365
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
366 :type my_task: Task
367 :param my_task: The associated task in the task tree.
368 :rtype: boolean
369 :returns: True on success, False otherwise.
a7e4ffc Initial import.
knipknap authored
370 """
371 raise NotImplementedError("Trigger not supported by this task.")
372
b385af1 More variable renaming magic.
knipknap authored
373 def _on_complete(self, my_task):
a7e4ffc Initial import.
knipknap authored
374 """
375 Return True on success, False otherwise. Should not be overwritten,
376 overwrite _on_complete_hook() instead.
377
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
378 :type my_task: Task
379 :param my_task: The associated task in the task tree.
380 :rtype: boolean
381 :returns: True on success, False otherwise.
a7e4ffc Initial import.
knipknap authored
382 """
b385af1 More variable renaming magic.
knipknap authored
383 assert my_task is not None
a7e4ffc Initial import.
knipknap authored
384
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
385 if my_task.workflow.debug:
adb0700 @ztane python 3 support (python 2 not yet tested)
ztane authored
386 print("Executing task:", my_task.get_name())
a7e4ffc Initial import.
knipknap authored
387
da3c3ab @knipknap no longer interpret the return value of TaskSpec._on_complete_hook().
authored
388 self._on_complete_hook(my_task)
a7e4ffc Initial import.
knipknap authored
389
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
390 # Notify the Workflow.
391 my_task.workflow._task_completed_notify(my_task)
a7e4ffc Initial import.
knipknap authored
392
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
393 if my_task.workflow.debug:
c7bfc91 @knipknap fix: s/outer_job/outer_workflow/g.
authored
394 if hasattr(my_task.workflow, "outer_workflow"):
395 my_task.workflow.outer_workflow.task_tree.dump()
a7e4ffc Initial import.
knipknap authored
396
478ccbe @knipknap rename SpiffWorkflow.Job to SpiffWorkflow.Workflow.
authored
397 self.completed_event.emit(my_task.workflow, my_task)
a7e4ffc Initial import.
knipknap authored
398 return True
399
b385af1 More variable renaming magic.
knipknap authored
400 def _on_complete_hook(self, my_task):
a7e4ffc Initial import.
knipknap authored
401 """
402 A hook into _on_complete() that does the task specific work.
403
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
404 :type my_task: Task
405 :param my_task: The associated task in the task tree.
406 :rtype: bool
407 :returns: True on success, False otherwise.
a7e4ffc Initial import.
knipknap authored
408 """
409 # If we have more than one output, implicitly split.
3d7b77c @knipknap replace Task._update_children by Task._sync_children() that uses much…
authored
410 for child in my_task.children:
411 child.task_spec._update_state(child)
b1bc5c5 @knipknap add serialize() and deserialize() methods for all TaskSpec methods.
authored
412
3362bd1 @knipknap TaskSpec.serialize() and .deserialize(): pass kwargs to the serializer.
authored
413 def serialize(self, serializer, **kwargs):
b1bc5c5 @knipknap add serialize() and deserialize() methods for all TaskSpec methods.
authored
414 """
415 Serializes the instance using the provided serializer.
416
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
417 .. note::
394aeb4 @knipknap minor cleanups and API doc improvements.
authored
418
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
419 The events of a TaskSpec are not serialized. If you
420 use them, make sure to re-connect them once the spec is
421 deserialized.
422
423 :type serializer: L{SpiffWorkflow.storage.Serializer}
424 :param serializer: The serializer to use.
425 :type kwargs: dict
426 :param kwargs: Passed to the serializer.
427 :rtype: object
428 :returns: The serialized object.
b1bc5c5 @knipknap add serialize() and deserialize() methods for all TaskSpec methods.
authored
429 """
3362bd1 @knipknap TaskSpec.serialize() and .deserialize(): pass kwargs to the serializer.
authored
430 return serializer._serialize_task_spec(self, **kwargs)
b1bc5c5 @knipknap add serialize() and deserialize() methods for all TaskSpec methods.
authored
431
432 @classmethod
caa845d @ziadsawalha PEP8 cleanups.
ziadsawalha authored
433 def deserialize(cls, serializer, wf_spec, s_state, **kwargs):
394aeb4 @knipknap minor cleanups and API doc improvements.
authored
434 """
435 Deserializes the instance using the provided serializer.
436
11dba14 @knipknap port API doc syntax to Sphinx, except for cross-references, which I s…
authored
437 .. note::
438
439 The events of a TaskSpec are not serialized. If you
440 use them, make sure to re-connect them once the spec is
441 deserialized.
442
443 :type serializer: L{SpiffWorkflow.storage.Serializer}
444 :param serializer: The serializer to use.
445 :type wf_spec: L{SpiffWorkflow.spec.WorkflowSpec}
446 :param wf_spec: An instance of the WorkflowSpec.
447 :type s_state: object
448 :param s_state: The serialized task specification object.
449 :type kwargs: dict
450 :param kwargs: Passed to the serializer.
451 :rtype: TaskSpec
452 :returns: The task specification instance.
394aeb4 @knipknap minor cleanups and API doc improvements.
authored
453 """
4c702cb @ziadsawalha fix TaskSpec.serialize() and improved TaskSpecTest.testSerialize().
ziadsawalha authored
454 instance = cls(wf_spec, s_state['name'])
455 return serializer._deserialize_task_spec(wf_spec,
456 s_state,
457 instance,
458 **kwargs)
Something went wrong with that request. Please try again.