Tech News
← Back to articles

Cancelling async Rust

read original related products more articles

This is an edited, written version of my RustConf 2025 talk about cancellations in async Rust. Like the written version of my RustConf 2023 talk, I’ve tried to retain the feel of a talk while making it readable as a standalone blog entry. Some links:

Let’s start with a simple example – you decide to read from a channel in a loop and gather a bunch of messages:

loop { match rx . recv (). await { Ok ( msg ) => process ( msg ), Err ( _ ) => return , } }

All good, nothing wrong with this, but you realize sometimes the channel is empty for long periods of time, so you add a timeout and print a message:

loop { match timeout ( Duration :: from_secs ( 5 ), rx . recv ()). await { Ok ( Ok ( msg )) => process ( msg ), Ok ( Err ( _ )) => return , Err ( _ ) => println! ( "no messages for 5 seconds" ), } }

There’s nothing wrong with this code—it behaves as expected.

Now you realize you need to write a bunch of messages out to a channel in a loop:

loop { let msg = next_message (); match tx . send ( msg ). await { Ok ( _ ) => println! ( "sent successfully" ), Err ( _ ) => return , } }

But sometimes the channel gets too full and blocks, so you add a timeout and print a message:

loop { let msg = next_message (); match timeout ( Duration :: from_secs ( 5 ), tx . send ( msg )). await { Ok ( Ok ( _ )) => println! ( "sent successfully" ), Ok ( Err ( _ )) => return , Err ( _ ) => println! ( "no space for 5 seconds" ), } }

... continue reading