Structured Concurrency: Managing the Hierarchical Cancelation and Error Handling by James Ward

Learn how Structured Concurrency enables predictable concurrent task management through hierarchical scopes, with patterns for cancellation, error handling & resource cleanup.

Key takeaways
  • Structured Concurrency provides a hierarchical model for managing concurrent tasks through scopes, making cancellation and error handling more predictable

  • Key benefits include automatic resource cleanup, proper cancellation propagation, and cleaner error handling compared to unstructured approaches like Go routines

  • Common patterns include:

    • Race operations (first-to-complete wins)
    • Hedging requests (sending backup requests to reduce p99 latency)
    • Resource management with supervised scopes
    • Many-to-many concurrent operations
  • Scope Values provide thread-local immutable state that can be accessed within a concurrent scope without explicitly passing values, useful for request IDs and tracing

  • Virtual threads in Java Loom enable efficient structured concurrency without blocking OS threads

  • Error handling strategies:

    • Shutdown on success - cancel other tasks when one succeeds
    • Shutdown on error - propagate errors while allowing other tasks to complete
    • Contained error handling within scopes
  • Resource management requires careful handling of:

    • Opening/closing connections
    • Cleanup on cancellation
    • Proper scoping of resources
    • Automatic resource disposal
  • Different implementations available across languages:

    • Java Loom’s structured task scopes
    • Kotlin coroutines
    • Scala libraries (Ox, ZIO)
    • OCaml, Rust implementations
  • Helps prevent common concurrency issues like:

    • Memory leaks
    • Dangling connections
    • Resource cleanup failures
    • Callback hell
  • Testing structured concurrency implementations can be done through “obstacle courses” that verify proper handling of concurrent scenarios