Skip to content

Rename PublishHandle to PublishFuture #4635

@suzmue

Description

@suzmue

The original naming was inspired by JoinHandle. However, the PublishHandle doesn't have many of the properties of a handle (aborting, etc) and just implements Future. By updating the naming to be PublishFuture it is a closer to what it represents.

Why not fn publish() -> impl Future?

We choose to return a named type PublishFuture instead of impl Future to make it clear that this is a synchronous function with an asynchronous result.

It is possible to get the behavior we want with the following function signature and implementation:

pub fn publish(&self, msg: Message) -> impl Future<Output=Result<String>> {
	let (tx, rx) = tokio::sync::oneshot::channel(); // create resp channel.
       self.tx.send(ToWorker::Publish(BundledMessage { msg, tx }))
	// There are no await's until this point, so the first two lines execute
	// as soon as publish is called, even without awaiting.
	tx.await
}

This however looks a lot like async fn publish(), but it has very different behavior:.

// This async fn looks like it should be the same as above.
pub async fn publish(&self, msg: Message) -> Result<String> {
	let (tx, rx) = tokio::sync::oneshot::channel(); // create resp channel.
       self.tx.send(ToWorker::Publish(BundledMessage { msg, tx }))
	tx.await
}

// .. but it gets desugared to the following with the whole body wrapped in an
// async block.
pub fn publish(&self, msg: Message) -> impl Future<Output=Result<String>> {
	async {
		let (tx, rx) = tokio::sync::oneshot::channel(); // create resp channel.
  	     self.tx.send(ToWorker::Publish(BundledMessage { msg, tx }))
		// There are no await's until this point, so the first two lines execute
		// as soon as publish is called.
		tx.await
	}
}

The first two lines no longer get executed right away. So these two functions that look the same at the function signature actually behave very differently. The syntax sugar is so common, that user expectations are going to be more aligned with the second.

By choosing a named return type, we make it clear that something different is happening than would be expected from a typical async fn.

Metadata

Metadata

Assignees

Labels

api: pubsubIssues related to the Pub/Sub API.

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions