Your teaching example is solid, but when you're actually scraping in the wild, you gotta add guards to keep bad retries from sneaking through, plus entry and exit hooks so your side effects don't end up scattered all over your codebase like socks after laundry. And here's the thing -- FSMs are great at blocking impossible state combos, but if you're running distributed scrapers across multiple workers, you need idempotency keys and locks to handle timing weirdness. And when you save state after a crash, don't just store the state name - grab a timestamp too, because resuming a backoff timer from 24 hours ago is the kind of silent bug that'll haunt your logs. Once you're past prototype stage, libraries like transitions Python or XState JS basically pay for themselves with built-in visualization and guard support. Overal, this should help people actually see the FSMs they're already building and start being intentional about it
Your teaching example is solid, but when you're actually scraping in the wild, you gotta add guards to keep bad retries from sneaking through, plus entry and exit hooks so your side effects don't end up scattered all over your codebase like socks after laundry. And here's the thing -- FSMs are great at blocking impossible state combos, but if you're running distributed scrapers across multiple workers, you need idempotency keys and locks to handle timing weirdness. And when you save state after a crash, don't just store the state name - grab a timestamp too, because resuming a backoff timer from 24 hours ago is the kind of silent bug that'll haunt your logs. Once you're past prototype stage, libraries like transitions Python or XState JS basically pay for themselves with built-in visualization and guard support. Overal, this should help people actually see the FSMs they're already building and start being intentional about it