Some history: I believe a long time ago, publishing API on crates.io was synchronous -- it only return an http response to cargo publish after publishing was fully finished. This then was changed on serve side to async publishing for some technical reason I don't remember.
While I haven't tried it myself, it looks like cargo-release has a similar loop which updates metadata, looks for the published crate, instead of trying to create a temp package in its wait_for_publish function. There is a sleep there, but just for a second presumably to avoid being too busy.
Assuming we don't want to make changes to how crates.io the wait_for_publish() function mentioned by @ratmice is probably the best you can do.
The underlying problem is that we don't have a mechanism to let the server asynchronously push events down to us. One possible idea is for crates.io to gain a pub-sub service where you can subscribe to be notified about certain events, then cargo-release and friends would temporarily subscribe to notifications for just that package, do the release, then go to sleep until crates.io says it's been released.
How does docs.rs know when a new package has been published so it can generate docs? Is it just polling for changes every X minutes, too?
Currently yes, every minute (maybe slightly longer, I didn’t check) it updates a local index clone and checks if there are new crates. There’s plans to move that to a webhook, but that’d be a rust-lang internal infrastructure thing.