On Fri, May 20, 2011 at 5:22 AM, Charlie
<quanl...@gmail.com> wrote:
Eduardo:
I have implemented the feature on top of the 0.11.0 release.
Here is a description of the doit task timeout feature implemented:
A task can have a timeout attribute.
The attribute value can be of type integer or datetime.timedelta.
When the value is an integer, the time unit is second.
A task may not have both run_once and timeout.
If a task is successfully run, it will timeout after the specified
time interval.
This is one way for the task to be out of date.
If a task has a timeout attribute and it has no dependency,
then, once it runs successfully, it will be skipped until it
timeouts.
I'm not sure what's the best way to send the implementation to you.
I'm going to email the files to you.
Best Regards!
Charlie
Hi,
I commit this feature into trunk.
(uptodate callables)
http://bazaar.launchpad.net/~schettino72/doit/trunk/revision/394
(timeout)
http://bazaar.launchpad.net/~schettino72/doit/trunk/revision/395I ended up with a solution based on Matt ideas...
uptodate callables
=================
* first I added support for callables on "uptodate" (this is what Charlie was calling "condition" and Matt "function_dep"). this function must return True/False/None...
* this callable must take at least 2 parameters "task" and "values". of course you can just ignore them and you can also add more parameters to the callable.
- The "task" parameter will give you access to task object. so you have access to its metadata and opportunity to modifiy the task itself!
- "values" is a dictionary with the values saved in the last successful execution of the task.
run_once
===========
with this new feature I could remove run_once from doit core and implement it as function to be passed to 'uptodate' attribute. the implementation is only 5 lines!
def run_once(task, values):
def save_executed(): # save a value to indicate this task was executed
return {'run-once': True}
task.insert_action(save_executed) # add an action to the task that is used only to save a value
return values.get('run-once', False) # check if this task was ever run before
def task_xxx():
....
'uptodate': [run_once],
timeout
============
i just adapted Charlie's code here. I put a wrapper function that returns a callable
def timeout(timeout_limit):
if isinstance(timeout_limit, datetime.timedelta): # convert timeout_limit to int and check invalid input
limit_sec = timeout_limit.seconds
elif isinstance(timeout_limit, int):
limit_sec = timeout_limit
else:
msg = "timeout should be datetime.timedelta or int got %r "
raise Exception(msg % timeout_limit)
def uptodate_timeout(task, values):
def save_now(): # save time from successful execution
return {'success-time': time.time()}
task.insert_action(save_now) # add action to task to save time
last_success = values.get('success-time', None) # retrieve time from last successful execution
if last_success is None: # check first time execution
return False
return (time.time() - last_success) < limit_sec # check task expired timeout
return uptodate_timeout
def task_test3():
return {
'actions': ['echo test 3; date'],
'uptodate': [timeout(10)],
'verbosity': 2,
}
##############################
so both run_once and timeout could be implemented by a user without modifying doit code. for convenience i added these 2 on doit.tools.
Matt, this way cover you function_dep usage?
cheers,
Eduardo