Hard Pausable Macro Example
This example demonstrates how to create a robust, long-running task class that correctly handles the Engine's "Interrupt" and "Stop" signals.
Key Concepts:
- Persistence: Using a class allows you to store state (self.counter) easily.
- Hard Pause Safety: catching TaskInterruptedException to prevent loop breakage.
- Cleanup: Using 'finally' to ensure resources are closed on Stop.
Implementation:
| examples/interrupt_pause_macro.py |
|---|
| class DatabaseUpdaterTask:
"""
A simulated task that processes records in a loop.
It demonstrates safe pausing and graceful shutdown.
"""
def __init__(self):
self.records_processed = 0
self.is_connected = False
def connectDB(self, controller: Controller):
"""Simulate opening a resource."""
controller.log("π Connecting to database...")
self.is_connected = True
yield from taskSleep(0.5) # Slight delay to simulate connection time
def disconnectDB(self, controller: Controller):
"""Simulate closing a resource."""
if self.is_connected:
controller.log("π Disconnecting from database...")
self.is_connected = False
def run(self, controller: Controller):
"""
The main entry point called by the Engine.
"""
yield from self.connectDB(controller)
try:
# --- MAIN LOOP ---
while self.records_processed < 20:
# 1. THE SAFE SLEEP PATTERN
# We wrap the sleep in a try/except block.
# If we don't, a Pause signal would crash this 'while' loop immediately!
try:
controller.log(f"Processing record #{self.records_processed}...")
# Simulate work (takes 1 second)
yield from taskSleep(1.0)
self.records_processed += 1
except TaskInterruptedException:
# 2. HANDLE PAUSE
# The user clicked "Pause". We must explicitly wait here.
controller.log("βΈοΈ Task Paused safely. Waiting for resume...")
# This yields control until the task is resumed
yield from taskWaitForResume()
controller.log("βΆοΈ Resuming task loop...")
# When this returns, the loop continues naturally at the top
controller.log("β
Task completed successfully!")
finally:
# 3. HANDLE STOP / CLEANUP
# This block runs if:
# - The loop finishes normally.
# - The script crashes (Error).
# - The user clicks STOP (TaskAbortException).
self.disconnectDB(controller)
# --- Engine Registration ---
# Create a wrapper for our studio
def runSafeTask(controller: Controller):
task = DatabaseUpdaterTask()
yield from task.run(controller)
|
View the complete script
| examples/interrupt_pause_macro.py |
|---|
| """
Hard Pausable Macro Example
---------------------------
This example demonstrates how to create a robust, long-running task class
that correctly handles the Engine's "Interrupt" and "Stop" signals.
Key Concepts:
1. Persistence: Using a class allows you to store state (self.counter) easily.
2. Hard Pause Safety: catching TaskInterruptedException to prevent loop breakage.
3. Cleanup: Using 'finally' to ensure resources are closed on Stop.
"""
from macro_studio import MacroStudio, Controller, TaskInterruptedException, taskSleep, taskWaitForResume
class DatabaseUpdaterTask:
"""
A simulated task that processes records in a loop.
It demonstrates safe pausing and graceful shutdown.
"""
def __init__(self):
self.records_processed = 0
self.is_connected = False
def connectDB(self, controller: Controller):
"""Simulate opening a resource."""
controller.log("π Connecting to database...")
self.is_connected = True
yield from taskSleep(0.5) # Slight delay to simulate connection time
def disconnectDB(self, controller: Controller):
"""Simulate closing a resource."""
if self.is_connected:
controller.log("π Disconnecting from database...")
self.is_connected = False
def run(self, controller: Controller):
"""
The main entry point called by the Engine.
"""
yield from self.connectDB(controller)
try:
# --- MAIN LOOP ---
while self.records_processed < 20:
# 1. THE SAFE SLEEP PATTERN
# We wrap the sleep in a try/except block.
# If we don't, a Pause signal would crash this 'while' loop immediately!
try:
controller.log(f"Processing record #{self.records_processed}...")
# Simulate work (takes 1 second)
yield from taskSleep(1.0)
self.records_processed += 1
except TaskInterruptedException:
# 2. HANDLE PAUSE
# The user clicked "Pause". We must explicitly wait here.
controller.log("βΈοΈ Task Paused safely. Waiting for resume...")
# This yields control until the task is resumed
yield from taskWaitForResume()
controller.log("βΆοΈ Resuming task loop...")
# When this returns, the loop continues naturally at the top
controller.log("β
Task completed successfully!")
finally:
# 3. HANDLE STOP / CLEANUP
# This block runs if:
# - The loop finishes normally.
# - The script crashes (Error).
# - The user clicks STOP (TaskAbortException).
self.disconnectDB(controller)
# --- Engine Registration ---
# Create a wrapper for our studio
def runSafeTask(controller: Controller):
task = DatabaseUpdaterTask()
yield from task.run(controller)
if __name__ == '__main__':
studio = MacroStudio("Database Updater Macro")
studio.addBasicTask(runSafeTask)
studio.launch()
|