Skip to content

Commit 1df6c63

Browse files
committed
Update docs
1 parent baa0bb6 commit 1df6c63

File tree

3 files changed

+73
-4
lines changed

3 files changed

+73
-4
lines changed

docs/gallery/autogen/pyfunction.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,71 @@ def generate_structures(element: str, factors: list) -> dict:
7878
print("Generated scaled structures:")
7979
for key, value in result.items():
8080
print(key, value)
81+
82+
83+
# %%
84+
# Async functions
85+
# ---------------
86+
# ``pyfunction`` also supports Python's ``async`` functions. This is a powerful feature for
87+
# tasks that are I/O-bound (e.g., waiting for network requests, file operations) or for
88+
# running multiple tasks concurrently without blocking the AiiDA daemon.
89+
#
90+
# When you ``submit`` an async function, the call returns immediately with a process node,
91+
# allowing your script to continue running while the function executes in the background.
92+
#
93+
94+
import asyncio
95+
from aiida.engine import run, submit
96+
import datetime
97+
from aiida_pythonjob import prepare_pyfunction_inputs
98+
99+
100+
@pyfunction()
101+
async def add_async(x, y, time: float):
102+
"""A simple function that adds two numbers."""
103+
import asyncio
104+
105+
# Simulate asynchronous I/O or computation
106+
await asyncio.sleep(time)
107+
return x + y
108+
109+
110+
inputs = prepare_pyfunction_inputs(
111+
add_async,
112+
function_inputs={"x": 2, "y": 3, "time": 2.0},
113+
)
114+
115+
node = submit(add_async, **inputs)
116+
117+
# %%
118+
# Here is an example to monitor external events or conditions without blocking.
119+
# Here is an example that waits until a specified time.
120+
#
121+
122+
123+
@pyfunction()
124+
async def monitor_time(time: datetime.datetime):
125+
# monitor until the specified time
126+
while datetime.datetime.now() < time:
127+
print("Waiting...")
128+
await asyncio.sleep(0.5)
129+
130+
131+
inputs = prepare_pyfunction_inputs(
132+
monitor_time,
133+
function_inputs={"time": datetime.datetime.now() + datetime.timedelta(seconds=5)},
134+
)
135+
136+
node = submit(monitor_time, **inputs)
137+
138+
# %%#
139+
# Killing an async process
140+
# ------------------------
141+
# Since async functions run as regular AiiDA processes, they can be controlled and killed
142+
# programmatically. This is useful for managing long-running or stuck tasks.
143+
# You can kill a running async function using the AiiDA command line interface.
144+
#
145+
# .. code-block:: bash
146+
#
147+
# $ verdi process kill <pk>
148+
#
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1+
from .common_data import DateTimeData
12
from .pickled_data import PickledData
23
from .serializer import general_serializer, serialize_to_aiida_nodes
34

4-
__all__ = ("PickledData", "general_serializer", "serialize_to_aiida_nodes")
5+
__all__ = ("PickledData", "general_serializer", "serialize_to_aiida_nodes", "DateTimeData")

tests/test_async.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,17 @@ def test_async_function_raises_produces_exit_code():
4747
def test_async_function_kill():
4848
inputs = prepare_pyfunction_inputs(
4949
add_async,
50-
function_inputs={"x": 1, "y": 2, "t": 20},
50+
function_inputs={"x": 1, "y": 2, "t": 30},
5151
)
5252
node = submit(PyFunction, **inputs)
5353
# wait process to start
5454
time.sleep(2)
5555
control.kill_processes(
5656
[node],
5757
all_entries=None,
58-
timeout=5,
58+
timeout=10,
5959
)
6060
# wait kill to take effect
61-
time.sleep(5)
61+
time.sleep(10)
6262
assert node.is_killed
6363
assert "Killed through" in node.process_status

0 commit comments

Comments
 (0)