Settable Futures and Timers

767 views
Skip to first unread message

Gareth

unread,
Oct 5, 2011, 6:29:08 PM10/5/11
to guava-discuss
Hello,

I started using guava a few weeks ago and I am finding features such
as the ImmutableMap and ListenableFuture/SettableFuture very useful.
Thank you for all the hard work!

One thing I do very often though is that I use a SettableFuture
together with a Timer (i.e. if some action has not occurred within a
certain time period, cancel the future). I was wondering, in a future
release, do you think it may be useful to be able to create a
SettableFuture which cancels itself after a certain period of time?

e.g. I was thinking something like this (off the top of my head):

(1) Create an interface SettableFuture which encompasses the current
SettableFuture methods.

(2) Create a new interface SettableFutureFactory which can create a
SettableFuture with and without a timeout. e.g.:

public interface SettableFutureFactory {
<V> SettableFuture<V> create();

// the "timeoutRunnable" is for the future creator to do timeout
cleanup, not for the future user
<V> SettableFuture<V> create(long timeout, Runnable
timeoutRunnable);

}

A default implementation of the SettableFutureFactory would be passed
a Java Timer on initialization (ugh - unfortunately there is no timer
interface in Java). Users of the guava interface, of course, could
also create their own implementation which passes in their own timer
implementation.

What do you think?

thanks in advance,
Gareth

Chris Povirk

unread,
Oct 5, 2011, 6:36:12 PM10/5/11
to Gareth, guava-discuss
> I started using guava a few weeks ago and I am finding features such
> as the ImmutableMap and ListenableFuture/SettableFuture very useful.
> Thank you for all the hard work!

Thanks, we're glad to hear it.

> One thing I do very often though is that I use a SettableFuture
> together with a Timer (i.e. if some action has not occurred within a
> certain time period, cancel the future). I was wondering, in a future
> release, do you think it may be useful to be able to create a
> SettableFuture which cancels itself after a certain period of time?
>
> e.g. I was thinking something like this (off the top of my head):
>
> (1) Create an interface SettableFuture which encompasses the current
> SettableFuture methods.
>
> (2) Create a new interface SettableFutureFactory which can create a
> SettableFuture with and without a timeout. e.g.:
>
> public interface SettableFutureFactory {
>    <V> SettableFuture<V> create();
>
>    // the "timeoutRunnable" is for the future creator to do timeout
> cleanup, not for the future user
>    <V> SettableFuture<V> create(long timeout, Runnable
> timeoutRunnable);
>
> }
>
> A default implementation of the SettableFutureFactory would be passed
> a Java Timer on initialization (ugh - unfortunately there is no timer
> interface in Java). Users of the guava interface, of course, could
> also create their own implementation which passes in their own timer
> implementation.

I guess this could work with any kind of Future, not just
SettableFuture. It could be:

Futures.cancelIn(30, SECONDS, /* interrupt = */ true, executor,
future1, future2, ...);

(Timer is semi-deprecated in favor of ScheduledExecutorService, so we
might as well use that.)

If this is something people would find useful, we could take a look.
On the other hand, it's competing with get(30, SECONDS), the usual way
of setting a deadline when dealing with a Future.

Chris Povirk

unread,
Oct 5, 2011, 6:39:19 PM10/5/11
to Gareth, guava-discuss
> Futures.cancelIn(30, SECONDS, /* interrupt = */ true, executor,
> future1, future2, ...);

Of course, this amounts to...

executor.schedule(new Runnable() { public void run() {
future.cancel(true) } }, 30, SECONDS);

...as you're probably aware from implementing most of it.

Also, I should have replied to this:

> // the "timeoutRunnable" is for the future creator to do timeout
> cleanup, not for the future user
> <V> SettableFuture<V> create(long timeout, Runnable
> timeoutRunnable);

You might want to look at using AbstractFuture instead of
SettableFuture. It provides an interruptTask() method that you can
implement to perform cleanup actions when cancel(true) is called.

Gareth

unread,
Oct 5, 2011, 11:51:34 PM10/5/11
to guava-discuss
Thanks for the quick response!

I guess I could use the ScheduledExecutorService and create my own
implementation
if I did not want to use the ScheduledThreadPoolExecutor threading
model (it would be nicer
if the ScheduledExecutorService also returned a ListenableFuture :)).

With my request, I guess I am just trying to hide the boilerplate
synchronization between my SettableFuture and this ScheduledFuture
behind a library (i.e. if future one completes first cancel future
two, if future two completes first cancel future one).

You are right. For my implementation I should extend AbstractFuture.
Unfortunately though AbstractFuture doesn't have set and setException
as public methods and the SettableFuture class is final so I can't
extend that...so I would either need to expose my future
implementation class to the future creator or expose a new interface
which includes the public SettableFuture methods set and setException.

Anyway, thanks again for the response.

Gareth

Anthony Zana

unread,
Oct 6, 2011, 10:54:35 AM10/6/11
to Gareth, guava-discuss

I guess I could use the ScheduledExecutorService and create my own
implementation
if I did not want to use the ScheduledThreadPoolExecutor threading
model (it would be nicer
if the ScheduledExecutorService also returned a ListenableFuture :)).

Minor point, but in Release 11, all Future-returning methods on ListeningScheduledExecutorService (obtainable via MoreExecutors.listeningDecorator) will return a ListenableFuture.  


On Oct 5, 6:39 pm, Chris Povirk <cpov...@google.com> wrote:
> > Futures.cancelIn(30, SECONDS, /* interrupt = */ true, executor,
> > future1, future2, ...);
>
> Of course, this amounts to...
>
> executor.schedule(new Runnable() { public void run() {
> future.cancel(true) } }, 30, SECONDS);
>
> ...as you're probably aware from implementing most of it.
>
> Also, I should have replied to this:
>
> >    // the "timeoutRunnable" is for the future creator to do timeout
> > cleanup, not for the future user
> >    <V> SettableFuture<V> create(long timeout, Runnable
> > timeoutRunnable);
>
> You might want to look at using AbstractFuture instead of
> SettableFuture.  It provides an interruptTask() method that you can
> implement to perform cleanup actions when cancel(true) is called.




--
Anthony Zana
Software Engineer, Pittsburgh
Cell: 412-841-6279
Reply all
Reply to author
Forward
0 new messages