OK, here’s the promised explanation of yesterday’s bug.

One person correctly identified the issue and reached out to me. (Good spot Ian!)

So what was the issue?

Yesterday, I showed some code that was intended to work on both coding and blogging, but if one ran that code, one would find that a lot of coding happened, but very little (if any!) blogging. At best, we’d think about blogging and then jump into an endless loop of coding.

If you didn’t run the code, you might have first expected that the issue was no coding would happen because none of the functions invoked in code() were ever .awaited. If think_about_code(), write_code(), debug_code(), rewrite_code(), and release_code() were async functions, this would be true! We’d construct futures, but never poll them, and no coding work would ever actually be done. Intentions without execution don’t amount to much.

The issue is essentially that we’re not .await-ing anything in code(), but not because of unused futures!

As I mentioned above, we end up doing lots of coding, and only ever think about blogging, if that! Why?

Because all of the functions invoked in code() are synchronous, we can’t ever .await them, and since we don’t .await anything, we never yield.

Since we’re invoking code() and blog() together in a select!, both get scheduled for execution on the same thread.

If code() never yields back to the runtime, the runtime can’t poll any other tasks.

This highlights the cooperative nature of async Rust programming.