Skip to content

request: return ListenableFutures in PubSub async methods rather than bare Futures  #1148

Closed

Description

@mattnworb

The com.google.cloud.pubsub.PubSub interface defines async operations which return java.util.concurrent.Future values.

For anyone who uses the ListenableFuture concept from Guava (or CompletableFutures in Java 8), these Futures have to be adapted into ListenableFutures by spawning a thread that blocks on the Future.get() return.

It would be much more convenient if the Futures returned from PubSub were actually ListenableFuture instances (even if the interface did not define the return value to be ListenableFuture) - then it would not be necessary for users to block one thread per future they wish to adapt into a ListenableFuture.

For instance, internally PubSubImpl.pullAsync(final String subscription, int maxMessages) is implemented by using the listenable-like com.google.cloud.pubsub.spi.PubSubRpc.PullFuture and attaching callbacks to it, but the returned Future is an anonymous subclass of Future created by Futures.lazyTransform(..).

Is it a conscious decision to avoid using ListenableFutures in the interfaces defined in gcloud-java-pubsub and other clients?

It seems like the com.google.cloud.pubsub.spi layer has access to ListenableFuture instances via the generated grpc client code (like subscriberApi.acknowledgeCallable().futureCall(request)) but then these are discarded in the PubSubImpl layer.

Activity

  1. mziccard commented on Aug 10, 2016

    @mziccard
    Contributor

    Is it a conscious decision to avoid using ListenableFutures in the interfaces defined in gcloud-java-pubsub and other clients?

    Yes, it's a conscious decision. We don't want to expose Guava-related classes in our interfaces and we still want to support Java 7 (for GAE and Android, mainly).

    Could MessageConsumer pullAsync(String subscription, MessageProcessor callback, PullOption... options) help? If not, what is it missing that you need (I would be happy to add more features)?

  2. mattnworb commented on Aug 10, 2016

    @mattnworb
    Author

    Thanks @mziccard for the fast reply.

    MessageConsumer is great - it perfectly fits my needs for consuming messages. It is awesome to not have to implement something that pulls messages in a loop and processes them in our own code.

    The (minor) pain point comes more in code that deals with methods like Future<String> publishAsync(String topic, Message msg), when I would like to be able to transform the returned future to some other type or combine it with another future. We are heavy users of ListenableFuture and find it natural to transform and otherwise chain ListenableFutures together, so it is a small annoyance to have to use JdkFutureAdapters.listenInPoolThread and create a thread that blocks on Future.get() to be able to adapt this response to a ListenableFuture.

    I understand not wanting to return Guava types in the PubSub interface, but wouldn't it be possible to return ListenableFuture implementations (SettableFuture, etc) in the PubSub implementation? This way adapters like JdkFutureAdapters would avoid having to spawn a blocked thread since the returned future would pass a if (future instanceof ListenableFuture) ... check.

  3. mziccard commented on Aug 11, 2016

    @mziccard
    Contributor

    I understand not wanting to return Guava types in the PubSub interface, but wouldn't it be possible to return ListenableFuture implementations (SettableFuture, etc) in the PubSub implementation?

    I will look into this, I'll keep you posted!

  4. added a commit that references this issue on Feb 26, 2026
  5. added a commit that references this issue on Mar 20, 2026
  6. added a commit that references this issue on Mar 30, 2026
  7. added a commit that references this issue on Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions