google-apis-rs / google-cloud-rs

Asynchronous Rust bindings for Google Cloud Platform APIs.
176 stars 48 forks source link

fix(pubsub): Changed default `max_messages` #44

Closed Hirevo closed 3 years ago

Hirevo commented 3 years ago

This PR changes the default max_message option for ReceiveOptions from 5 to 1.

The rationale for this has been mentioned in #33, but here is the gist of it:

As we now have a new method for receiving message which offers more control over how it is done (Subscription::receive_with_options), I have been thinking about how the original Subscription::receive might be used.
I suspect it will be used for simple cases like:

while let Some(message) = subscription.receive().await {
    // some long computation here...
    message.ack().await?;
}

(notice that each message is processed sequentially within the same async task)

In that case, if we buffered 5 messages in the first receive call (as we could have, with the old default), it is possible that some of the buffered messages acknowledgement time expired or are considerably lowered when their time to be processed comes.

So we make the default be max_messages: 1 to make that easy case work better, while people can still go for the more scalable way of doing things which is eager pulling combined with independent concurrent tasks:

let opts = ReceiveOptions { max_messages: 5, ..Default::default() };
while let Some(message) = subscription.receive_with_options(opts.clone()).await {
    task::spawn(async move {
        // some long computation here...
        message.ack().await?;
    });
}

(here, each message is processed in a new independent task, which allows to handle more of them concurrently)

At the end of the day, we should still come around to write some documentation about this better pattern for handling Pub/Sub messages, even though these patterns aren't just about how to interact with GCP.