Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
fslpy
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michiel Cottaar
fslpy
Commits
37545321
Commit
37545321
authored
8 years ago
by
Paul McCarthy
Browse files
Options
Downloads
Patches
Plain Diff
async.idle has option to drop previously enqueued task with the same name
parent
a77d968b
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
fsl/utils/async.py
+54
-14
54 additions, 14 deletions
fsl/utils/async.py
with
54 additions
and
14 deletions
fsl/utils/async.py
+
54
−
14
View file @
37545321
...
@@ -22,6 +22,7 @@ Idle tasks
...
@@ -22,6 +22,7 @@ Idle tasks
idle
idle
idleWhen
idleWhen
inIdle
inIdle
cancelIdle
getIdleTimeout
getIdleTimeout
setIdleTimeout
setIdleTimeout
...
@@ -180,8 +181,8 @@ loop.
...
@@ -180,8 +181,8 @@ loop.
"""
"""
_idleQueue
Se
t
=
set
()
_idleQueue
Dic
t
=
{}
"""
A ``
se
t`` containing the names of all named tasks which are
"""
A ``
dic
t`` containing the names of all named tasks which are
currently queued on the idle loop (see the ``name`` parameter to the
currently queued on the idle loop (see the ``name`` parameter to the
:func:`idle` function).
:func:`idle` function).
"""
"""
...
@@ -259,7 +260,7 @@ def _wxIdleLoop(ev):
...
@@ -259,7 +260,7 @@ def _wxIdleLoop(ev):
import
wx
import
wx
global
_idleQueue
global
_idleQueue
global
_idleQueue
Se
t
global
_idleQueue
Dic
t
global
_idleTimer
global
_idleTimer
global
_idleCallRate
global
_idleCallRate
...
@@ -308,7 +309,8 @@ def _wxIdleLoop(ev):
...
@@ -308,7 +309,8 @@ def _wxIdleLoop(ev):
taskName
,
type
(
e
).
__name__
,
str
(
e
)),
exc_info
=
True
)
taskName
,
type
(
e
).
__name__
,
str
(
e
)),
exc_info
=
True
)
if
task
.
name
is
not
None
:
if
task
.
name
is
not
None
:
_idleQueueSet
.
discard
(
task
.
name
)
try
:
_idleQueueDict
.
pop
(
task
.
name
)
except
KeyError
:
pass
if
_idleQueue
.
qsize
()
>
queueSizeOffset
:
if
_idleQueue
.
qsize
()
>
queueSizeOffset
:
ev
.
RequestMore
()
ev
.
RequestMore
()
...
@@ -320,9 +322,20 @@ def inIdle(taskName):
...
@@ -320,9 +322,20 @@ def inIdle(taskName):
"""
Returns ``True`` if a task with the given name is queued on the
"""
Returns ``True`` if a task with the given name is queued on the
idle loop (or is currently running), ``False`` otherwise.
idle loop (or is currently running), ``False`` otherwise.
"""
"""
global
_idleQueueSet
global
_idleQueueDict
return
taskName
in
_idleQueueSet
return
taskName
in
_idleQueueDict
def
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 called ``taskName`` exists.
"""
global
_idleQueueDict
_idleQueueDict
[
taskName
].
timeout
=
-
1
def
idle
(
task
,
*
args
,
**
kwargs
):
def
idle
(
task
,
*
args
,
**
kwargs
):
"""
Run the given task on a ``wx.EVT_IDLE`` event.
"""
Run the given task on a ``wx.EVT_IDLE`` event.
...
@@ -344,6 +357,13 @@ def idle(task, *args, **kwargs):
...
@@ -344,6 +357,13 @@ def idle(task, *args, **kwargs):
scheduled to be called on the idle loop, the function
scheduled to be called on the idle loop, the function
is not called, and is dropped from the queue.
is not called, and is dropped from the queue.
:arg dropIfQueued: Optional. If provided, must be provided as a keyword
argument. If ``True``, and a task with the given
``name`` is already enqueud, that function is dropped
from the queue, and the new task is enqueued. Defaults
to ``False``. This argument takes precedence over the
``skipIfQueued`` argument.
:arg skipIfQueued: Optional. If provided, must be provided as a keyword
:arg skipIfQueued: Optional. If provided, must be provided as a keyword
argument. If ``True``, and a task with the given
argument. If ``True``, and a task with the given
``name`` is already enqueud, (or is running), the
``name`` is already enqueud, (or is running), the
...
@@ -369,22 +389,28 @@ def idle(task, *args, **kwargs):
...
@@ -369,22 +389,28 @@ def idle(task, *args, **kwargs):
This is because, if the required time has not elapsed when
This is because, if the required time has not elapsed when
the task is popped from the queue, it will be re-queued.
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 the ``skipIfQueued`` or ``dropIfQueued`` 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
.. note:: You will run into difficulties if you schedule a function that
expects/accepts its own keyword arguments called ``name``,
expects/accepts its own keyword arguments called ``name``,
``skipIfQueued``, ``after``, ``timeout``, or ``alwaysQueue``.
``skipIfQueued``, ``dropIfQueued``, ``after``, ``timeout``, or
``alwaysQueue``.
"""
"""
global
_idleRegistered
global
_idleRegistered
global
_idleTimer
global
_idleTimer
global
_idleQueue
global
_idleQueue
global
_idleQueue
Se
t
global
_idleQueue
Dic
t
schedtime
=
time
.
time
()
schedtime
=
time
.
time
()
timeout
=
kwargs
.
pop
(
'
timeout
'
,
0
)
timeout
=
kwargs
.
pop
(
'
timeout
'
,
0
)
after
=
kwargs
.
pop
(
'
after
'
,
0
)
after
=
kwargs
.
pop
(
'
after
'
,
0
)
name
=
kwargs
.
pop
(
'
name
'
,
None
)
name
=
kwargs
.
pop
(
'
name
'
,
None
)
skipIfQueued
=
kwargs
.
pop
(
'
skipIfQueued
'
,
None
)
dropIfQueued
=
kwargs
.
pop
(
'
dropIfQueued
'
,
False
)
skipIfQueued
=
kwargs
.
pop
(
'
skipIfQueued
'
,
False
)
alwaysQueue
=
kwargs
.
pop
(
'
alwaysQueue
'
,
False
)
alwaysQueue
=
kwargs
.
pop
(
'
alwaysQueue
'
,
False
)
if
alwaysQueue
or
_haveWX
():
if
alwaysQueue
or
_haveWX
():
...
@@ -399,10 +425,24 @@ def idle(task, *args, **kwargs):
...
@@ -399,10 +425,24 @@ def idle(task, *args, **kwargs):
_idleTimer
.
Bind
(
wx
.
EVT_TIMER
,
_wxIdleLoop
)
_idleTimer
.
Bind
(
wx
.
EVT_TIMER
,
_wxIdleLoop
)
if
name
is
not
None
and
skipIfQueued
and
inIdle
(
name
):
if
name
is
not
None
and
inIdle
(
name
):
log
.
debug
(
'
Idle task ({}) is already queued - dropping
'
'
it
'
.
format
(
getattr
(
task
,
'
__name__
'
,
'
<unknown>
'
)))
if
dropIfQueued
:
return
# The cancelIdle function sets the old
# task timeout to -1, so it won't get
# executed. But the task is left in the
# _idleQueue, and in the _idleQueueDict.
# In the latter, the old task gets
# overwritten with the new task below.
cancelIdle
(
name
)
log
.
debug
(
'
Idle task ({}) is already queued -
'
'
dropping the old task
'
.
format
(
name
))
elif
skipIfQueued
:
log
.
debug
(
'
Idle task ({}) is already queued
'
'
- skipping it
'
.
format
(
name
))
return
log
.
debug
(
'
Scheduling idle task ({}) on wx idle
'
log
.
debug
(
'
Scheduling idle task ({}) on wx idle
'
'
loop
'
.
format
(
getattr
(
task
,
'
__name__
'
,
'
<unknown>
'
)))
'
loop
'
.
format
(
getattr
(
task
,
'
__name__
'
,
'
<unknown>
'
)))
...
@@ -418,7 +458,7 @@ def idle(task, *args, **kwargs):
...
@@ -418,7 +458,7 @@ def idle(task, *args, **kwargs):
_idleQueue
.
put_nowait
(
idleTask
)
_idleQueue
.
put_nowait
(
idleTask
)
if
name
is
not
None
:
if
name
is
not
None
:
_idleQueue
Set
.
add
(
name
)
_idleQueue
Dict
[
name
]
=
idleTask
else
:
else
:
time
.
sleep
(
after
)
time
.
sleep
(
after
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment