The dbzero.wait method provides an efficient way to synchronize processes by pausing the current thread until a specific database state is reached.
dbzero.wait()
Blocks execution until the database prefix reaches a target transaction number or a timeout occurs. This is a highly efficient, thread-safe mechanism for waiting on updates from other processes, consuming minimal CPU resources while waiting.
dbzero.wait(prefix: str, state_num: int, timeout: int) -> boolParameters:
- prefix (
str): The name of the database prefix to monitor for changes. You can get the current prefix name usingdbzero.get_current_prefix().name. - state_num (
int): The target state number (transaction count) to wait for. You can get the current state number withdbzero.get_state_num(prefix). - timeout (
int): The maximum time to wait in milliseconds.
Returns:
bool: ReturnsTrueif the database reached or surpassed the targetstate_numwithin the specifiedtimeout. ReturnsFalseif the timeout was exceeded. It will returnTrueimmediately if the current state number is already greater than or equal to the target.
Description
In multi-process applications, you often need a "reader" process to react to data changes made by a "writer" process. A common but inefficient way to do this is by polling—repeatedly calling dbzero.refresh() inside a loop.
The dbzero.wait() method offers a much better solution. It uses an underlying operating system event to block the calling thread, which remains dormant until another process commits a transaction. This avoids busy-waiting and is the recommended way to wait for changes.
There is also an asyncio compatible version, dbzero.async_wait(prefix, state_num), which returns an awaitable future.
Examples
The following example demonstrates a writer process committing new objects while a reader process efficiently waits for a batch of transactions to complete.
<Tabs items=SynchronousAsynchronous> <Tabs.Tab> ```python
import multiprocessing
import time
import dbzero as db0
DB0_DIR = "/tmp/db0_wait_example"
# Ensure the directory is clean for the example
# In a real app, you might not do this
import shutil
shutil.rmtree(DB0_DIR, ignore_errors=True)
def writer_process(prefix):
"""This process creates new objects and commits them."""
dbzero.init(DB0_DIR)
dbzero.open(prefix, "rw")
for i in range(10):
_ = dbzero.memo(lambda: f"Object {i}")()
dbzero.commit()
time.sleep(0.1) # Simulate some work
dbzero.close()
# --- Main Process (Reader) ---
dbzero.init(DB0_DIR)
dbzero.open("my_prefix", "rw")
prefix_name = dbzero.get_current_prefix().name
dbzero.close() # Close to start fresh in read-mode
# Start the writer process
p = multiprocessing.Process(target=writer_process, args=(prefix_name,))
p.start()
# Open in read-only mode to listen for changes
dbzero.init(DB0_DIR)
dbzero.open(prefix_name, "r")
# Get the initial state number
initial_state = dbzero.get_state_num(prefix_name)
print(f"Initial state number: {initial_state}")
target_state = initial_state + 5
print(f"Waiting to reach state {target_state}...")
# Wait for 5 transactions to be committed by the writer
# We'll use a 2-second timeout (2000 ms)
success = dbzero.wait(prefix_name, target_state, 2000)
if success:
print(f"Success! Current state is {dbzero.get_state_num(prefix_name)}")
else:
print("Wait timed out!")
# Wait for the writer to finish
p.join()
# Expected output:
# Initial state number: 1
# Waiting to reach state 6...
# Success! Current state is 6 (or higher)</Tabs.Tab> <Tabs.Tab> ```python filename="async_wait_example.py" import multiprocessing import time import asyncio import dbzero as db0
DB0_DIR = "/tmp/db0_async_wait_example"
# Ensure the directory is clean for the example
import shutil
shutil.rmtree(DB0_DIR, ignore_errors=True)
def writer_process(prefix):
"""This process creates new objects and commits them."""
dbzero.init(DB0_DIR)
dbzero.open(prefix, "rw")
for i in range(10):
_ = dbzero.memo(lambda: f"Object {i}")()
dbzero.commit()
time.sleep(0.1) # Simulate some work
dbzero.close()
async def main():
# --- Setup ---
dbzero.init(DB0_DIR)
dbzero.open("my_async_prefix", "rw")
prefix_name = dbzero.get_current_prefix().name
dbzero.close()
p = multiprocessing.Process(target=writer_process, args=(prefix_name,))
p.start()
dbzero.init(DB0_DIR)
dbzero.open(prefix_name, "r")
# --- Wait Logic ---
initial_state = dbzero.get_state_num(prefix_name)
target_state = initial_state + 5
print(f"Waiting to reach state {target_state}...")
try:
# Use asyncio.wait_for to handle the timeout
await asyncio.wait_for(
dbzero.async_wait(prefix_name, target_state),
timeout=2.0
)
print(f"Success! Current state is {dbzero.get_state_num(prefix_name)}")
except asyncio.TimeoutError:
print("Wait timed out!")
p.join()
if __name__ == "__main__":
asyncio.run(main())
# Expected output:
# Waiting to reach state 6...
# Success! Current state is 6 (or higher)
```
\</Tabs.Tab\>
\</Tabs\>