How to link futures with Guava?

I am trying to create a small service to accept a file download, unzip it, and then delete the downloaded file. These three steps should be fettered as futures. I am using the Google Guava library.

The working process:

The future is to download the file, if the operation is completed, then in the future to unzip the file. If unpacking is performed, the original downloaded file is deleted in the future.

But to be honest, I don’t understand how I will connect futures and even how to create them on Guava. The documentation is simply concise and unclear. Well, there is a transform method, but no concrete example. chain method is deprecated.

I miss the RxJava library.

+6
source share
2 answers

For this purpose, Guava extends the Future interface with ListenableFuture .

Something like this should work:

 Runnable downloader, unzipper; ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); service.submit(downloader).addListener(unzipper, service); 

I would include deleting the file in unzipper, as this is an almost instantaneous action, and this will complicate the code to separate it.

+2
source

Futures.transform not compatible with the chain, like RxJava, but you can still use it to configure Future , which are dependent on each other. Here is a concrete example:

 final ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); final ListenableFuture<FileClass> fileFuture = service.submit(() -> fileDownloader.download()) final ListenableFuture<UnzippedFileClass> unzippedFileFuture = Futures.transform(fileFuture, //need to cast this lambda (Function<FileClass, UnzippedFileClass>) file -> fileUnzipper.unzip(file)); final ListenableFuture<Void> deletedFileFuture = Futures.transform(unzippedFileFuture, (Function<UnzippedFileClass, Void>) unzippedFile -> fileDeleter.delete(unzippedFile)); deletedFileFuture.get(); //or however you want to wait for the result 

This example assumes fileDownloader.download() returns an instance of FileClass , fileUpzipper.unzip() returns UnzippedFileClass , etc. If fileDownloader.download() instead returns ListenableFuture<FileClass> , use AsyncFunction instead of Function .

This example also uses Java 8 lambdas for short. If you are not using Java 8, go to anonymous implementations of Function or AsyncFunction:

 Futures.transform(fileFuture, new AsyncFunction<FileClass, UpzippedFileClass>() { @Override public ListenableFuture<UnzippedFileClass> apply(final FileClass input) throws Exception { return fileUnzipper.unzip(); } }); 

More information about transform here: http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/util/concurrent/Futures.html#transform (scroll or search "transform" - deep binding is currently taking place)

+2
source

Source: https://habr.com/ru/post/980923/


All Articles