Mission Asyncable - The Basics of Asyncs - Part 1: Cancellation
This post is part of F# Advent Calendar 2020. Check out other posts here.
- Secret Async Man
- Where can I specify CancellationTokens?
On my team, we’ve been running into a few microservices stalling and other production issues, due to some nuanced assumptions around Async and cancellations. Knowing the fundamentals is important, and I thought it’d be a useful experience to review them, perhaps from a different angle.
One of the more “invisible” aspects of Async workflows in F# are CancellationTokens. They are constructs that are implicitly passed through Async workflows to enable cooperative cancellation.
Let’s break that down. They’re implicitly passed through in the sense that a parent Async’s
CancellationToken is forwarded to child workflows it spawns. By spawns, I mean a child workflow that is handed over control to, usually via
do! on an
Async<'T> (Note: this propagation can be circumvented, as will be explained below). By cooperative, we mean that a “well-behaved” Async workflow is supposed to inspect the token to see if cancellation’s been requested. It behaves like a good citizen by cancelling the current workflow as quickly as possible, but this is only an expectation, there are no guarantees it will do so.