workflow example
This commit is contained in:
105
actions/simulate_work.py
Normal file
105
actions/simulate_work.py
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simulate Work Action - Python Example Pack
|
||||
|
||||
Simulates a unit of work that takes a configurable amount of time.
|
||||
Returns structured JSON output with timing information and an optional
|
||||
payload. Useful for testing workflows, the timeline DAG visualizer,
|
||||
and execution monitoring.
|
||||
|
||||
Parameters (via stdin JSON):
|
||||
duration_seconds - How long to simulate work (float, default: 1.0)
|
||||
label - A label for this work unit (string, default: "work")
|
||||
fail - Whether to simulate a failure (bool, default: false)
|
||||
fail_after - If failing, fail after this many seconds (float, default: 0)
|
||||
output_data - Arbitrary JSON data to include in the result (default: null)
|
||||
|
||||
Output (JSON):
|
||||
label - The label that was passed in
|
||||
duration_seconds - Actual elapsed time
|
||||
requested_seconds - The requested duration
|
||||
output_data - The pass-through data (if any)
|
||||
success - Always true on success (failures exit non-zero)
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
params = json.loads(sys.stdin.readline())
|
||||
|
||||
duration_seconds = float(params.get("duration_seconds", 1.0))
|
||||
label = params.get("label", "work")
|
||||
fail = params.get("fail", False)
|
||||
fail_after = float(params.get("fail_after", 0))
|
||||
output_data = params.get("output_data", None)
|
||||
|
||||
# Clamp duration to a reasonable range
|
||||
duration_seconds = max(0.0, min(duration_seconds, 300.0))
|
||||
|
||||
print(
|
||||
f"[simulate_work] Starting '{label}' for {duration_seconds}s", file=sys.stderr
|
||||
)
|
||||
|
||||
start = time.time()
|
||||
|
||||
if fail and fail_after > 0:
|
||||
# Sleep for fail_after seconds then crash
|
||||
time.sleep(min(fail_after, duration_seconds))
|
||||
elapsed = round(time.time() - start, 3)
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"error": f"Simulated failure in '{label}' after {elapsed}s",
|
||||
"label": label,
|
||||
"elapsed": elapsed,
|
||||
}
|
||||
),
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
if fail:
|
||||
# Immediate failure
|
||||
print(
|
||||
json.dumps(
|
||||
{
|
||||
"error": f"Simulated immediate failure in '{label}'",
|
||||
"label": label,
|
||||
}
|
||||
),
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# Simulate work with periodic progress to stderr
|
||||
remaining = duration_seconds
|
||||
while remaining > 0:
|
||||
chunk = min(remaining, 1.0)
|
||||
time.sleep(chunk)
|
||||
remaining -= chunk
|
||||
elapsed = round(time.time() - start, 3)
|
||||
pct = min(100.0, round((elapsed / max(duration_seconds, 0.001)) * 100, 1))
|
||||
print(
|
||||
f"[simulate_work] '{label}' progress: {pct}% ({elapsed}s)", file=sys.stderr
|
||||
)
|
||||
|
||||
elapsed = round(time.time() - start, 3)
|
||||
|
||||
result = {
|
||||
"label": label,
|
||||
"duration_seconds": elapsed,
|
||||
"requested_seconds": duration_seconds,
|
||||
"success": True,
|
||||
}
|
||||
if output_data is not None:
|
||||
result["output_data"] = output_data
|
||||
|
||||
print(json.dumps(result))
|
||||
print(f"[simulate_work] '{label}' completed in {elapsed}s", file=sys.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user