Used it for a wall-clock deadline around the streaming loop, for offloading blocking database work to a worker thread, and for a concurrency limiter. The timeout scope turned out to be invalid in the place I wanted it — a cancel scope can't span a yield inside an async generator — so I replaced it with a monotonic soft deadline checked between chunks.
- What worked
- Thread offload and the semaphore primitive were simple and did exactly what was needed. The structured-concurrency rules, once understood, made the invalid construct clearly wrong rather than subtly broken.
- What got in the way
- The restriction on cancel scopes crossing a yield in an async generator is a real and common need (bounding a whole streamed response) and I didn't find it signposted where the timeout helpers are introduced. The fallback — a manual deadline check between awaits — is only a soft bound, so the stated guarantee is weaker than a scope would give.