Cancelling async Rust(sunshowers.io)

108 points by todsacerdoti 4 hours ago | 21 comments

  • arifalkner 1 minute ago
    Great talk! One thing that would have been nice to call out for n00bs like myself is how in SOP Futures can't cancelled. I knew that .await took ownership of the future so that drop() could not be called on it, so given how futures are lazy, it wasn't clear to me how to cancel a future after .await had been called. I later researched how select! and Abortable() did this, but could be nice to include a callout in the beginning of your talk if you ever do it again. Otherwise, nice work!
  • Animats 24 minutes ago
    In the initial example, it's not clear what the desired behavior is. If the queue is full, the basic options are drop something, block and wait, or panic. Timing out on a block is usually deadlock detection. He writes "It turns out that this code is often incorrect, because not all messages make their way to the channel." Well, yes. You're out of resources. Now what?

    What's he trying to do? Get a clean program shutdown? That's moderately difficult in threaded programs, and async has problems, too. The use case here is unclear.

    The real use cases involve when you're sending messages back and forth to a remote site, and the remote site goes away. Now you need to dispose of the state on your end.

    [-]
    • AceJohnny2 20 minutes ago
      > He writes

      They go by they/she

      https://sunshowers.io/about/

    • sunshowers 6 minutes ago
      Ideally, what you would like to do is buffer up the message until there's space in the channel. I cover this later in the talk under "What can be done".
  • CaptainOfCoit 3 hours ago
    Less clickbaity title: Cancellations in async Rust.

    It's really not about "cancelling async Rust" which is what I expected, even if it didn't make much sense.

    [-]
    • sunshowers 2 hours ago
      As the author of the talk/blog post, I was definitely going for a bit of a moral valence in the title, in the sense that future cancellations are very hard to reason about and what I call the least Rusty part of Rust. But it admittedly is a bit clickbaity too.
      [-]
      • acedTrex 2 hours ago
        I initially skipped reading it because i thought it was another drama post about maintainers a la all the nixos stuff lately.
    • binary132 2 hours ago
      if only
      [-]
      • zackmorris 57 minutes ago
        +1 this.

        IMHO async is an anti-pattern, and probably the final straw that will prevent me from ever finishing learning Rust. Once one learns pass-by-value and copy-on-write semantics (Clojure, PHP arrays), the world starts looking like a spreadsheet instead of spaghetti code. I feel that a Rust-like language could be built with no borrow checker, simply by allocating twice the memory. Since that gets ever-less expensive, I'm just not willing to die on the hill of efficiency anymore. I predict that someday Rust will be relegated to porting scripting languages to a bare-metal runtime, but will not be recommended for new work.

        That said, I think that Rust would make a great teaching tool in an academic setting, as the epitome of imperative languages. Maybe something great will come of it, like Swift from Objective-C or Kotlin from Java. And having grown up on C++, I have a soft spot in my heart for solving the hard problems in the fastest way possible. Maybe a voxel game in Rust, I dunno.

        [-]
    • happytoexplain 2 hours ago
      As in the pop-culture concept of cancelling? That's what you assumed the topic "cancelling async <language name>" was going to be about??

      Or am I missing context?

      [-]
      • hansvm 1 hour ago
        That's what I assumed. I know languages have to handle cancellations in async code, but Rust has had a fair amount of drama over the years, and I assumed the title was accurate and reflected that some drama was happening.
      • thehamkercat 1 hour ago
        they probably assumed something like some_running_async_task.cancel()
  • Matthias247 2 hours ago
    Some other material that has been written by me on that topic:

    - Proposal from 2020 about async functions which are forced to run to completion (and thereby would use graceful cancellation if necessary). Quite old, but I still feel that no better idea has come up so far. https://github.com/Matthias247/rfcs/pull/1

    - Proposal for unified cancellation between sync and async Rust ("A case for CancellationTokens" - https://gist.github.com/Matthias247/354941ebcc4d2270d07ff0c6...)

    - Exploration of an implementation of the above: https://github.com/Matthias247/min_cancel_token

  • CodeBrad 3 hours ago
    This was one of my favorite talks from RustConf this year! The distinction between cancel safety and cancel correctness is really helpful.

    Glad to see it converted to a blog post. Talks are great, but blogs are much easier to share and reference.

    [-]
    • sunshowers 2 hours ago
      Thanks! I definitely prefer reading blog posts over watching talks as well.
  • ossopite 42 minutes ago
    I think the send/recv with a timeout example is very interesting, because in a language where futures start running immediately without being polled, I think the situation is likely to be the opposite way around. send with a timeout is probably safe (you may still send if the timeout happened, which you might be sad about, but the message isn't lost), while recv with a timeout is probably unsafe, because you might read the message out of the channel but then discard it because you selected the timeout completion instead. And the fix is similar, you want to select either the timeout or 'something is available' from the channel, and if you select the latter you can peek to get the available data.
    [-]
    • sunshowers 8 minutes ago
      Thanks, that is a great point.
  • Panzerschrek 3 hours ago
    One should always keep in mind that await is always a potential return point. So, using await between two actions which always should be performed together should be avoided.
  • bryanlarsen 3 hours ago
    Timely! Was grumbling about this today as I added a "this function is cancel safe" to a new function's doc comment.

    I really hope we get async drop soon.