Simple example
Overview¶
This example demonstrates different ways that the same code can be executed. This is an overview of the four cells shown in the animation below.
- Define the coroutine function.
- Cell 'magic'
%callersprints a list of Caller instances and the thread in which it is executing. - A button is created and and it runs a loop twice:
- Creates any anyio event.
- Prints a statement.
- Waits for the button click to set the event.
- Cell 'magic'
- Execute
demonormally. - Execute
democoncurrently in a task. - Execute
demoin a thread.
In [1]:
Copied!
import ipywidgets as ipw
from aiologic import Event
from async_kernel import Caller, utils
async def demo():
%callers
caller = Caller() # Use caller set the event in the waiting thread
b = ipw.Button(description="Continue")
display(b)
for i in range(1, 3):
b.description = f"Continue {i}"
event = Event()
b.on_click(lambda _: caller.call_soon(event.set)) # noqa: B023
print(f"Waiting {i}", end="\r")
await event
b.close()
print("\nDone!")
import ipywidgets as ipw
from aiologic import Event
from async_kernel import Caller, utils
async def demo():
%callers
caller = Caller() # Use caller set the event in the waiting thread
b = ipw.Button(description="Continue")
display(b)
for i in range(1, 3):
b.description = f"Continue {i}"
event = Event()
b.on_click(lambda _: caller.call_soon(event.set)) # noqa: B023
print(f"Waiting {i}", end="\r")
await event
b.close()
print("\nDone!")
In [2]:
Copied!
print(utils.get_tags())
await demo()
print(utils.get_tags())
await demo()
[]
Name Running Protected Thread
───────────────────────────────────────────────────────────────────────────────────────────
Shell ✓ 🔐 <_MainThread(MainThread, started 140134800642176)> ← current
Control ✓ 🔐 <Thread(Control, started daemon 140134649427648)>
Button(description='Continue', style=ButtonStyle())
Waiting 1
In [3]:
Copied!
# task
await demo()
# task
await demo()
Name Running Protected Thread
───────────────────────────────────────────────────────────────────────────────────────────
Shell ✓ 🔐 <_MainThread(MainThread, started 140134800642176)> ← current
Control ✓ 🔐 <Thread(Control, started daemon 140134649427648)>
Button(description='Continue', style=ButtonStyle())
Waiting 1
In [4]:
Copied!
# thread
await demo()
# thread
await demo()
Name Running Protected Thread
──────────────────────────────────────────────────────────────────────────────────────────────────────
Shell ✓ 🔐 <_MainThread(MainThread, started 140134800642176)>
Control ✓ 🔐 <Thread(Control, started daemon 140134649427648)>
✓ <Thread(async_kernel_caller, started daemon 140134229993152)> ← current
Button(description='Continue', style=ButtonStyle())
Waiting 1
Caller.as_completed¶
See also: the caller notebook.
In [5]:
Copied!
async for _ in Caller().as_completed(Caller().call_soon(demo) for _ in range(2)):
pass
async for _ in Caller().as_completed(Caller().call_soon(demo) for _ in range(2)):
pass
Name Running Protected Thread
──────────────────────────────────────────────────────────────────────────────────────────────────────
Shell ✓ 🔐 <_MainThread(MainThread, started 140134800642176)> ← current
Control ✓ 🔐 <Thread(Control, started daemon 140134649427648)>
✓ <Thread(async_kernel_caller, started daemon 140134229993152)>
Button(description='Continue', style=ButtonStyle())
Waiting 1
Name Running Protected Thread
──────────────────────────────────────────────────────────────────────────────────────────────────────
Shell ✓ 🔐 <_MainThread(MainThread, started 140134800642176)> ← current
Control ✓ 🔐 <Thread(Control, started daemon 140134649427648)>
✓ <Thread(async_kernel_caller, started daemon 140134229993152)>
Button(description='Continue', style=ButtonStyle())
Waiting 1