Set up Manual Threading#
Enabling threading in Panel like we saw in the automatic threading guide is a simple way to achieve concurrency, however sometimes we need more control. Below we will demonstrate an example of a Thread
which we start in the background to process items we put in a queue for processing. We simulate the processing with a time.sleep
but it could be any long-running computation. The threading.Condition
allows us to manipulate the global shared queue
.
import time
import threading
c = threading.Condition()
button = pn.widgets.Button(name='Click to launch')
text = pn.widgets.StaticText()
queue = []
def callback():
global queue
while True:
c.acquire()
for i, event in enumerate(queue):
text.value = f'Processing item {i+1} of {len(queue)} items in queue.'
... # Do something with the event
time.sleep(2)
queue.clear()
text.value = "Queue empty"
c.release()
time.sleep(1)
thread = threading.Thread(target=callback)
thread.start()
Now we will create a callback that puts new items for processing on the queue when a button is clicked:
def on_click(event):
queue.append(event)
button.on_click(on_click)
pn.Row(button, text).servable()
Since the processing happens on a separate thread the application itself can still remain responsive to further user input (such as putting new items on the queue).