fsl.utils.idle
¶
This module provides functions and classes for running tasks asynchronously, either in an idle loop, or on a separate thread.
Note
The idle functions in this module are intended to be run from
within a wx
application. However, they will still work without
wx
, albeit with slightly modified behaviour.
Idle tasks¶
Blocks for the specified number of seconds, yielding to the main |
|
Run the given task on a |
|
Poll the |
|
Returns |
|
If a task with the given |
|
Reset the internal |
|
Returns the current |
|
Set the |
The idle()
function is a simple way to run a task on an wx
EVT_IDLE
event handler. This effectively performs the same job as the
run()
function, but is more suitable for short tasks which do not
warrant running in a separate thread.
The EVT_IDLE
event is generated automatically by wx
. However, there
are some circumstances in which EVT_IDLE
will not be generated, and
pending events may be left on the queue. For this reason, the
_wxIdleLoop()
will occasionally use a wx.Timer
to ensure that it
continues to be called. The time-out used by this Timer
can be queried
and set via the getIdleTimeout()
and setIdleTimeout()
functions.
Thread tasks¶
Run the given |
|
Creates and starts a new |
|
The |
The run()
function simply runs a task in a separate thread. This
doesn’t seem like a worthy task to have a function of its own, but the
run()
function additionally provides the ability to schedule another
function to run on the wx.MainLoop
when the original function has
completed. This therefore gives us a simple way to run a computationally
intensitve task off the main GUI thread (preventing the GUI from locking up),
and to perform some clean up/refresh afterwards.
The wait()
function is given one or more Thread
instances, and a
task to run. It waits until all the threads have finished, and then runs
the task (via idle()
).
The TaskThread
class is a simple thread which runs a queue of tasks.
Other facilities¶
The idle
module also defines the mutex()
decorator, which is
intended to be used to mark the methods of a class as being mutually exclusive.
The mutex
decorator uses the MutexFactory
class to do its work.
-
fsl.utils.idle.
run
(task, onFinish=None, onError=None, name=None)¶ Run the given
task
in a separate thread.- Parameters
task – The function to run. Must accept no arguments.
onFinish – An optional function to schedule (on the
wx.MainLoop
, viaidle()
) once thetask
has finished.onError – An optional function to be called (on the
wx.MainLoop
, viaidle()
) if thetask
raises an error. Passed theException
that was raised.name – An optional name to use for this task in log statements.
- Returns
A reference to the
Thread
that was created.
Note
If a
wx
application is not running, thetask
andonFinish
functions will simply be called directly, and the return value will beNone
.
-
fsl.utils.idle.
idleReset
()¶ Reset the internal
idle()
queue state.In a normal execution environment, this function will never need to be called. However, in an execution environment where multiple
wx.App
instances are created, run, and destroyed sequentially, this function will need to be called after eachwx.App
has been destroyed. Otherwise theidle
function will not work during exeution of subsequentwx.App
instances.
-
fsl.utils.idle.
getIdleTimeout
()¶ Returns the current
wx
idle loop time out/call rate.
-
fsl.utils.idle.
setIdleTimeout
(timeout=None)¶ Set the
wx
idle loop time out/call rate. Iftimeout
is not provided, or is set toNone
, the timeout is set to 200 milliseconds.
-
class
fsl.utils.idle.
IdleTask
(name, task, schedtime, after, timeout, args, kwargs)¶ Bases:
object
Container object used by the
idle()
and_wxIdleLoop()
functions.
-
fsl.utils.idle.
inIdle
(taskName)¶ Returns
True
if a task with the given name is queued on the idle loop (or is currently running),False
otherwise.
-
fsl.utils.idle.
cancelIdle
(taskName)¶ If a task with the given
taskName
is in the idle queue, it is cancelled. If the task is already running, it cannot be cancelled.A
KeyError
is raised if no task calledtaskName
exists.
-
fsl.utils.idle.
block
(secs, delta=0.01)¶ Blocks for the specified number of seconds, yielding to the main
wx
loop.If
wx
is not available, or awx
application is not running, this function is equivalent totime.sleep(secs)
.- Parameters
secs – Time in seconds to block
delta – Time in seconds to sleep between successive yields to
wx
.
-
fsl.utils.idle.
idle
(task, *args, **kwargs)¶ Run the given task on a
wx.EVT_IDLE
event.- Parameters
task – The task to run.
name – Optional. If provided, must be provided as a keyword argument. Specifies a name that can be used to query the state of this task via the
inIdle()
function.after – Optional. If provided, must be provided as a keyword argument. A time, in seconds, which specifies the amount of time to wait before running this task after it has been scheduled.
timeout – Optional. If provided, must be provided as a keyword argument. Specifies a time out, in seconds. If this amount of time passes before the function gets scheduled to be called on the idle loop, the function is not called, and is dropped from the queue.
dropIfQueued – Optional. If provided, must be provided as a keyword argument. If
True
, and a task with the givenname
is already enqueud, that function is dropped from the queue, and the new task is enqueued. Defaults toFalse
. This argument takes precedence over theskipIfQueued
argument.skipIfQueued – Optional. If provided, must be provided as a keyword argument. If
True
, and a task with the givenname
is already enqueud, (or is running), the function is not called. Defaults toFalse
.alwaysQueue – Optional. If provided, must be provided as a keyword argument. If
True
, and awx.MainLoop
is not running, the task is enqueued anyway, under the assumption that awx.MainLoop
will be started in the future. Note that, ifwx.App
has not yet been created, another call toidle
must be made after the app has been created for the original task to be executed. Ifwx
is not available, this parameter will be ignored, and the task executed directly.
All other arguments are passed through to the task function.
If a
wx.App
is not running, thetimeout
,name
andskipIfQueued
arguments are ignored. Instead, the call will sleep forafter
seconds, and then thetask
is called directly.Note
If the
after
argument is used, there is no guarantee that the task will be executed in the order that it is scheduled. This is because, if the required time has not elapsed when the task is popped from the queue, it will be re-queued.Note
If you schedule multiple tasks with the same
name
, and you do not use theskipIfQueued
ordropIfQueued
arguments, all of those tasks will be executed, but you will only be able to query/cancel the most recently enqueued task.Note
You will run into difficulties if you schedule a function that expects/accepts its own keyword arguments called
name
,skipIfQueued
,dropIfQueued
,after
,timeout
, oralwaysQueue
.
-
fsl.utils.idle.
idleWhen
(func, condition, *args, **kwargs)¶ Poll the
condition
function periodically, and schedulefunc
onidle()
when it returnsTrue
.- Parameters
func – Function to call.
condition – Function which returns
True
orFalse
. Thefunc
function is only called when thecondition
function returnsTrue
.pollTime – Must be passed as a keyword argument. Time (in seconds) to wait between successive calls to
when
. Defaults to0.2
.
-
fsl.utils.idle.
wait
(threads, task, *args, **kwargs)¶ Creates and starts a new
Thread
which waits for all of theThread
instances to finish (byjoin``ing them), and then runs the given ``task
viaidle()
.If the
direct
parameter isTrue
, or awx.App
is not running, this functionjoin``s the threads directly instead of creating a new ``Thread
to do so.- Parameters
threads – A
Thread
, or a sequence ofThread
instances to join. Elements in the sequence may beNone
.task – The task to run once all
threads
have completed.wait_direct – Must be passed as a keyword argument. If
True
, this function call willjoin
all of thethreads
, and then call thetask
. Otherwise (the default), this function will create a new thread tojoin
thethreads
, and will return immediately.
All other arguments are passed to the
task
function.Note
This function will not support
task
functions which expect a keyword argument calledwait_direct
.
-
class
fsl.utils.idle.
Task
(name, func, onFinish, args, kwargs)¶ Bases:
object
Container object which encapsulates a task that is run by a
TaskThread
.
-
exception
fsl.utils.idle.
TaskThreadVeto
¶ Bases:
Exception
Task functions which are added to a
TaskThread
may raise aTaskThreadVeto
error to skip processing of the task’sonFinish
handler (if one has been specified). See theTaskThread.enqueue()
method for more details.
-
class
fsl.utils.idle.
TaskThread
(*args, **kwargs)¶ Bases:
threading.Thread
The
TaskThread
is a simple thread which runs tasks. Tasks may be enqueued and dequeued.-
enqueue
(func, *args, **kwargs)¶ Enqueue a task to be executed.
- Parameters
func – The task function.
taskName – Task name. Must be specified as a keyword argument. Does not necessarily have to be a string, but must be hashable. If you wish to use the
dequeue()
orisQueued()
methods, you must provide a task name.onFinish – An optional function to be called (via
idle()
) when the task funtion has finished. Must be provided as a keyword argument. If thefunc
raises a :class`TaskThreadVeto` error, this function will not be called.
All other arguments are passed through to the task function when it is executed.
Note
If the specified
taskName
is not unique (i.e. another task with the same name may already be enqueued), theisQueued()
method will probably return invalid results.Warning
Make sure that your task function is not expecting keyword arguments called
taskName
oronFinish
!
-
isQueued
(name)¶ Returns
True
if a task with the given name is enqueued,False
otherwise.
-
dequeue
(name)¶ Dequeues a previously enqueued task.
- Parameters
name – The task to dequeue.
-
stop
()¶ Stop the
TaskThread
after any currently running task has completed.
-
waitUntilIdle
()¶ Causes the calling thread to block until the task queue is empty.
-
run
()¶ Run the
TaskThread
.
-
-
fsl.utils.idle.
mutex
(*args, **kwargs)¶ Decorator for use on methods of a class, which makes the method call mutually exclusive.
If you define a class which has one or more methods that must only be accessed by one thread at a time, you can use the
mutex
decorator to enforce this restriction. As a contrived example:class Example(object): def __init__(self): self.__sharedData = [] @mutex def dangerousMethod1(self, message): sefl.__sharedData.append(message) @mutex def dangerousMethod2(self): return sefl.__sharedData.pop()
The
@mutex
decorator will ensure that, at any point in time, only one thread is running either of thedangerousMethod1
ordangerousMethod2
methods.See the
MutexFactory`
-
class
fsl.utils.idle.
MutexFactory
(function)¶ Bases:
object
The
MutexFactory
is a placeholder for methods which have been decorated with themutex()
decorator. When the method of a class is decorated with@mutex
, aMutexFactory
is created.Later on, when the method is accessed on an instance, the
__get__()
method creates the true decorator function, and replaces the instance method with that decorator.Note
The
MutexFactory
adds an attribute called_async_mutex_lock
to all instances that have@mutex
-decorated methods.-
createLock
= <unlocked _thread.lock object>¶ This lock is used by all
MutexFactory
instances when a decorated instance method is accessed for the first time.The first time that a mutexed method is accessed on an instance, a new
threading.Lock
is created, to be shared by all mutexed methods of that instance. ThecreateLock
is used to ensure that this can only occur once for each instance.
-