All Projects → spotify → Completable Futures

spotify / Completable Futures

Licence: other
Utilities for working with futures in Java 8

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Completable Futures

memsocket
An asynchronous in-memory socket-like interface for Rust
Stars: ✭ 34 (-87.73%)
Mutual labels:  asynchronous
conductor
Mix both synchronous and asynchronous code without hassle
Stars: ✭ 58 (-79.06%)
Mutual labels:  asynchronous
Aiotutorial
code snippets for asyncio tutorial
Stars: ✭ 257 (-7.22%)
Mutual labels:  asynchronous
drone-cortexm
ARM® Cortex®-M platform crate for Drone, an Embedded Operating System.
Stars: ✭ 31 (-88.81%)
Mutual labels:  asynchronous
AlephBFT
Rust implementation of Aleph consensus protocol
Stars: ✭ 17 (-93.86%)
Mutual labels:  asynchronous
yerbie
A blazing fast job queue built for ease of use and scalability
Stars: ✭ 16 (-94.22%)
Mutual labels:  asynchronous
firetrap
This project is no longer maintained. Check out the fork (lib)unFTP instead.
Stars: ✭ 15 (-94.58%)
Mutual labels:  asynchronous
Drone Core
The core crate for Drone, an Embedded Operating System.
Stars: ✭ 263 (-5.05%)
Mutual labels:  asynchronous
python-logstash-async
Python logging handler for sending log events asynchronously to Logstash.
Stars: ✭ 141 (-49.1%)
Mutual labels:  asynchronous
Circuits
circuits is a Lightweight Event driven and Asynchronous Application Framework for the Python Programming Language with a strong Component Architecture.
Stars: ✭ 256 (-7.58%)
Mutual labels:  asynchronous
futura
Asynchronous Swift made easy. The project was made by Miquido. https://www.miquido.com/
Stars: ✭ 34 (-87.73%)
Mutual labels:  asynchronous
async-pidfd
Rust crate to use process file descriptors (pidfd) for Linux
Stars: ✭ 42 (-84.84%)
Mutual labels:  asynchronous
xtra
🎭 A tiny actor framework
Stars: ✭ 111 (-59.93%)
Mutual labels:  asynchronous
RepositoryHelpers
📦 Extensions for HttpClient and Custom Repository based on dapper
Stars: ✭ 22 (-92.06%)
Mutual labels:  asynchronous
React Reactive Form
Angular like reactive forms in React.
Stars: ✭ 259 (-6.5%)
Mutual labels:  asynchronous
SockNet
The easiest and fastest way to work with sockets in C#
Stars: ✭ 42 (-84.84%)
Mutual labels:  asynchronous
MojangSharp
A C# wrapper library for Mojang API (no longer actively maintained)
Stars: ✭ 38 (-86.28%)
Mutual labels:  asynchronous
Creed
Sophisticated and functionally-minded async with advanced features: coroutines, promises, ES2015 iterables, fantasy-land
Stars: ✭ 265 (-4.33%)
Mutual labels:  asynchronous
Zio
ZIO — A type-safe, composable library for async and concurrent programming in Scala
Stars: ✭ 3,167 (+1043.32%)
Mutual labels:  asynchronous
postage-rs
The feature-rich, portable async channel library
Stars: ✭ 122 (-55.96%)
Mutual labels:  asynchronous

completable-futures

Build Status Test Coverage Maven Central License

completable-futures is a set of utility functions to simplify working with asynchronous code in Java8.

Usage

Using completable-futures requires Java 8 but has no additional dependencies. It is meant to be included as a library in other software. To import it with maven, add this to your pom:

<dependency>
    <groupId>com.spotify</groupId>
    <artifactId>completable-futures</artifactId>
    <version>0.3.1</version>
</dependency>

Features

Combining more than two things

The builtin CompletableFuture API includes future.thenCombine(otherFuture, function) but if you want to combine more than two things it gets trickier. The CompletableFutures class contains the following APIs to simplify this use-case:

allAsList

If you want to join a list of futures of uniform type, use allAsList. This returns a future which completes to a list of all values of its inputs:

List<CompletableFuture<String>> futures = asList(completedFuture("a"), completedFuture("b"));
CompletableFuture<List<String>> joined = CompletableFutures.allAsList(futures);

allAsMap

If you want to join a map of key and value-futures, each of uniform type, use allAsMap. This returns a future which completes to a map of all key values of its inputs:

  Map<String, CompletableFuture<String>> futures = new HashMap() {{
    put("key", completedFuture("value"));
  }};
  CompletableFuture<Map<String, String>> joined = CompletableFutures.allAsMap(futures);

successfulAsList

Works like allAsList, but futures that fail will not fail the joined future. Instead, the defaultValueMapper function will be called once for each failed future and value returned will be put in the resulting list on the place corresponding to the failed future. The default value returned by the function may be anything, such as null or Optional.empty().

List<CompletableFuture<String>> input = asList(
    completedFuture("a"),
    exceptionallyCompletedFuture(new RuntimeException("boom")));
CompletableFuture<List<String>> joined = CompletableFutures.successfulAsList(input, t -> "default");

joinList

joinList is a stream collector that combines multiple futures into a list. This is handy if you apply an asynchronous operation to a collection of entities:

collection.stream()
    .map(this::someAsyncFunction)
    .collect(CompletableFutures.joinList())
    .thenApply(this::consumeList)

joinMap

joinMap is a stream collector that applies an asynchronous operation to each element of the stream, and associates the result of that operation to a key derived from the original element. This is useful when you need to keep the association between the entity that triggered the asynchronous operation and the result of that operation:

collection.stream()
    .collect(joinMap(this::toKey, this::someAsyncFunc))
    .thenApply(this::consumeMap)

combine

If you want to combine more than two futures of different types, use the combine method:

CompletableFutures.combine(f1, f2, (a, b) -> a + b);
CompletableFutures.combine(f1, f2, f3, (a, b, c) -> a + b + c);
CompletableFutures.combine(f1, f2, f3, f4, (a, b, c, d) -> a + b + c + d);
CompletableFutures.combine(f1, f2, f3, f4, f5, (a, b, c, d, e) -> a + b + c + d + e);

combineFutures

If you want to combine multiple futures into another future, use combineFutures:

CompletableFutures.combineFutures(f1, f2, (a, b) -> completedFuture(a + b));
CompletableFutures.combineFutures(f1, f2, f3, (a, b, c) -> completedFuture(a + b + c));
CompletableFutures.combineFutures(f1, f2, f3, f4, (a, b, c, d) -> completedFuture(a + b + c + d));
CompletableFutures.combineFutures(f1, f2, f3, f4, f5, (a, b, c, d, e) -> completedFuture(a + b + c + d + e));

Combine an arbitrary number of futures

If you want to combine more than six futures of different types, use the other combine method. Since it supports vararg usage, the function is now the first argument. The CombinedFutures object that is input to the function can be used to extract values from the input functions.

This is effectively the same thing as calling join() on the input future, but it's safer because calling .get(f) on a future that is not part of the combine, you will get an IllegalArgumentException.

This prevents accidental misuse where you would join on a future that is either not complete, or might never complete at all.

CompletionStage<String> f1;
CompletionStage<String> f2;
CompletionStage<String> result = combine(combined -> combined.get(f1) + combined.get(f2), f1, f2);

If you want to do this in a combineFutures form, you can do that like this:

CompletionStage<String> f1;
CompletionStage<String> f2;
CompletionStage<String> result = dereference(combine(combined -> completedFuture(combined.get(f1) + combined.get(f2)), f1, f2));

Scheduling

Polling an external resource

If you are dealing with a long-running external task that only exposes a polling API, you can transform that into a future like so:

Supplier<Optional<T>> pollingTask = () -> Optional.ofNullable(resource.result());
Duration frequency = Duration.ofSeconds(2);
CompletableFuture<T> result = CompletableFutures.poll(pollingTask, frequency, executor);

Missing parts of the CompletableFuture API

The CompletableFutures class includes utility functions for operating on futures that is missing from the builtin API.

handleCompose

Like CompletableFuture.handle but lets you return a new CompletionStage instead of a direct value.

CompletionStage<String> composed = handleCompose(future, (value, throwable) -> completedFuture("hello"));

exceptionallyCompose

Like CompletableFuture.exceptionally but lets you return a new CompletionStage instead of a direct value.

CompletionStage<String> composed = CompletableFutures.exceptionallyCompose(future, throwable -> completedFuture("fallback"));

dereference

Unwrap a CompletionStage<CompletionStage<T>> to a plain CompletionStage<T>.

CompletionStage<CompletionStage<String>> wrapped = completedFuture(completedFuture("hello"));
CompletionStage<String> unwrapped = CompletableFutures.dereference(wrapped);

exceptionallyCompletedFuture

Creates a new future that is already exceptionally completed with the given exception.

return CompletableFutures.exceptionallyCompletedFuture(new RuntimeException("boom"));

License

Copyright 2016 Spotify AB. Licensed under the Apache License, Version 2.0.

Code of Conduct

This project adheres to the Open Code of Conduct. By participating, you are expected to honor this code.

Releases

See the instructions in spotify/foss-root

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].