How to cancel asyncio's loop.call_later()? - python

If I schedule a callback using loop.call_later() (or with loop.call_at(), which behaves the same way), is it possible to cancel its execution?
Why? Let's say I schedule something to run one minute from now. However, due to some condition, the code decides to abort that execution (because it's not needed anymore), or alternatively decides to reschedule it for another time. The question is how to implement it using Python's asyncio?
If you are familiar with JavaScript, I'm looking for equivalents of setTimeout() and clearTimeout().

From the docs you linked:
An instance of asyncio.TimerHandle is returned which can be used to cancel the callback.
And from the docs of asyncio.Handle, a superclass of asyncio.TimerHandle:
cancel()
Cancel the callback. If the callback has already been canceled or executed, this method has no effect.
So just call the handle's cancel method.

Related

wxPython wx.CallAfter()

I work with wxpython and threads in my project. I think that I didn't understand well how to use wx.CallAfter and when to us it. I read few thing but I still didn't got the point. Someone can explain it to me?
In a nutshell, wx.CallAfter simply takes a callable and the parameters that should be passed to it, bundles that up into a custom event, and then posts that event to the application's pending event queue. When that event is dispatched the handler calls the given callable, passing the given parameters to it.
Originally wx.CallAfter was added in order to have an easy way to invoke code after the current and any other pending events have been processed. Since the event is always processed in the main UI thread, then it turns out that wx.CallAfter is also a convenient and safe way for a worker thread to cause some code to be run in the UI thread.

What does the bokeh decorator #without_document_lock() mean?

The bokeh server documentation includes an example of updating from unlocked callbacks. It states:
Normally Bokeh session callbacks recursively lock the document until all future work they initiate is complete. However, you may want to drive blocking computations from callbacks using Tornado’s ThreadPoolExecutor in an asynchronous callback. This can work, but requires the Bokeh provided without_document_lock() decorator to suppress the normal locking behavior.
What does this mean? Does it mean, for example, that without the decorator, then once invoked, a callback and anything it calls runs to completion before surrendering control back to the main IOLoop?
Whereas with the decorator, the main event loop continues while the callback executes?
What does this mean? Does it mean, for example, that without the decorator, then once invoked, a callback and anything it calls runs to completion before surrendering control back to the main IOLoop?
It means no other Bokeh callbacks will even start to execute while another one is in-flight with a lock on the Document, regardless of whether they are on different threads.
But you can override that, e.g. if you have a callback on a thread that does an expensive "non-Bokeh" computation, then updates a few Bokeh properties at the end. You can decorate that callback
to be #without_document_lock() so it can always start and do the expensive "non-Bokeh work" in the background, regardless of any other Bokeh callbacks that might be executing. You just have to follow the pattern in the link and put any actual Bokeh property updates in a "next tick" callback (all actual updates to Bokeh models have to occur in callbacks that have a Document lock, like a next tick callback)

Python Threading.Timer is calling command without waiting

I have a very basic Tkinter application that I'm trying to set to automatically refresh. I am using threading.Timer to trigger a function called go at the end of which cocalls the timer to reset it to run again.
def SetTimer():
t=threading.Timer(5,go())
t.start
SetTimer()
I've spent most of my afternoon trying to resolve this but I can't seem to figure out what I'm doing wrong. Based upon the other questions I've read I understand that each instance creates a separate thread with the timer, but why isn't it waiting for the time to elapse prior to triggering the function.
Use:
t=threading.Timer(5,go)
Note the go rather than go(). The parentheses tell Python to call the function. In contrast, go is a function object. Functions are "first-class" objects in Python; they can be passed to functions just like any other object.
Python evaluates the arguments to a function before calling the function. So using go() calls the go before calling threading.Timer. The value returned by go() gets sent to Timer, which is not what you want.
Note that all Tkinter UI code should be called from a single thread. For this reason, using Tkinter's root.after method is probably a better choice for what you want to do. The after method schedules a function to be called by Tkinter's mainloop. Here are some examples using after:
Tkinter and Threads
A rotating image

Does a Python threading.Condition.wait() suspend execution immediately?

If I call wait() on a python condition variable, does the calling thread suspend execution and yield or does it keep blocking until the next context switch?
The thread does yield. This yielding is due to the implementation of pthread_cond_wait or the equivalent suspension mechanism in in PyThread_acquire_lock. Since the condition variable is implemented using the system call interface, and Python uses native threading, the operating system scheduler is responsible for switching to another thread.
Additionally, the GIL is released before calling this deep into Python's internals. Finally the last piece of the puzzle is the call to acquire the lock in threading.Condition.wait.
The wait() method releases the lock, and then blocks until it is
awakened by a notify() or notifyAll() call for the same condition
variable in another thread. Once awakened, it re-acquires the lock and
returns. It is also possible to specify a timeout.
It blocks until the condition is notified.

How can I provide a "callback" to an API?

I was reading some module documentation and saw something I didn't understand, in the explanation of parameters for a method:
callback - callback function which will be called with argument
list equal to callbackargs+(result,)
as soon as calculation is done
callbackargs - additional arguments for callback function
group - job group, is used when wait(group) is called to wait for
jobs in a given group to finish
How can I call the method and correctly supply arguments for these parameters? What are they used for, and how does this "callback" scheme work?
A callback is a function provided by the consumer of an API that the API can then turn around and invoke (calling you back). If I setup a Dr.'s appointment, I can give them my phone number, so they can call me the day before to confirm the appointment. A callback is like that, except instead of just being a phone number, it can be arbitrary instructions like "send me an email at this address, and also call my secretary and have her put it in my calendar.
Callbacks are often used in situations where an action is asynchronous. If you need to call a function, and immediately continue working, you can't sit there wait for its return value to let you know what happened, so you provide a callback. When the function is done completely its asynchronous work it will then invoke your callback with some predetermined arguments (usually some you supply, and some about the status and result of the asynchronous action you requested).
If the Dr. is out of the office, or they are still working on the schedule, rather than having me wait on hold until he gets back, which could be several hours, we hang up, and once the appointment has been scheduled, they call me.
In this specific case, the documented method will compute the result, put it together with any callbackargs specified, and call callback, passing it those values as the arguments.
If you want some code to be executed as soon as the result is ready, put that code into a function and pass it as the callback argument. For example, supposing no other arguments are needed for that function:
def itsdone(result):
print(f"Done! result={result}")
...
submit(..., callback=itsdone)
For more on how this works in Python, see e.g. my presentation on the topic.
Looking at the link, just looks like a hook which is called.
callback - callback function which
will be called with argument
list equal to callbackargs+(result,)
as soon as calculation is done
The "as soon as calculation is done" bit seems ambiguous. The point, as far as I can see of this thing is that the submit() call distributes work to other servers and then returns. Because the finishing is asynchronous, rather block, it allows you to provide a function which is called when some unit of work finishes. If you do:
submit( ..., callback=work_finished, ... )
Then submit will ensure work_finished() is called when the unit of distributed work is completed on the target server.
When you call submit() you can provide a callback which is called in the same runtime as the caller of submit() ... and it is called after the distribution of the workload function is complete.
Kind of like "call foo(x,y) when you have done some stuff in submit()"
But yea, the documentation could be better. Have a ganders at the ppython source and see at which point the callback is called in submit()
A callback is a function you define that's later called by a function you call.
As an example, consider how AJAX works: you write code that calls a back-end server function. At some point in the future, it returns from that function (the "A" stands for Asynchronous, which is what the "Parallel" in "Parallel Python" is all about). Now - because your code calls the code on the server, you want it to tell you when it's done, and you want to do something with its results. It does so by calling your callback function.
When the called function completes, the standard way for it to tell you it's done is for you to tell it to call a function in your code. That's the callback function, and its job is to handle the results/output from the lower-level function you've called.
A callback is simply a function. In Python, functions are just more objects, and so the name of a function can be used as a variable, like so:
def func():
...
something(func)
Note that many functions which accept a callback as an argument usually require that the callback accept certain arguments. In this case, the callback function will need to accept a list of arguments specified in callbackargs.

Categories