Git Product home page Git Product logo

eventual's Introduction

Build Status

Eventual Providers

Guice add-ons to resolve future-provided dependencies.

<dependency>
  <groupId>org.immutables</groupId>
  <artifactId>eventual</artifactId>
  <version>1.1</version>
</dependency>

Creates special mix-in module created from defining class with special asynchronous transformation methods annotated with @EventuallyProvides, which is asynchronous analog to Guice's @Provides. Used to annotate asynchronous provider methods used to describe transformation of async values.

@Eventually.Provides
C combine(A a, B b) {
  return new C(a.a(), b.b());
}

In this provider method above we created binding for ListenableFuture<C> that will be functionally equivalent to the following regular @Provides method:

@Provides
ListenableFuture<C> combine(ListenableFuture<A> a, ListenableFuture<B> b) {
  return Futures.transform(Futures.allAsList(Arrays.asList(a, b)),
      (List<Object> input) -> {
        A a = (A) input.get(0);
        B b = (B) input.get(1);
        return new C(a.a(), b.b());
      });
}

Here's more involved example

@Singleton // all futures will be singletons
public class Providers { // no need to extend AbstractModule or implement Module

  @Eventually.Provides
  A createA() {
    return ...;
  }

  @Eventually.Provides
  ListenableFuture<B> loadB() {
    // loading of B is itself asyncronous, so we return future
    return ...;
  }

  @Eventually.Provides
  C combine(A a, B b) {
    // when A and B ready, we calculate C
    return new C(a.value(), b.calculate());
  }

  // Only exposed values can be injected between modules,
  // All other are hidden inside private module
  @Exposed
  @Eventually.Provides
  Z transformed(C c) {
    // when C is ready, we calculate Z from it
    return c.transformed();
  }
}

Module futureModule = EventualModules.definedBy(new Providers());

ListenableFuture<Module> completedModule =
    EventualModules.completedFrom(Guice.createInjector(futureModule));

// inject Z when all futures completed
Z z = Guice.createInjector(completedModule.get()).getInstance(Z.class);

Having dependency on ListenableFuture<A> and ListenableFuture<B>, this module exposed combined and transformed ListenableFuture<Z> available to injector.

While super-classes could be used and will be scanned for such methods, method overriding is not handled properly so avoid overriding provider methods. Use delegation to regular methods if some functionality should be implemented or overridden.

In order to customize dispatching, injector could provided with binding to @Eventually.Async Executor. So you need to mix in

On the very abstract level this library achieves transformation: P(A, B... Z) -> I(A, B... Z):

  • Define providers P(A, B... Z)
  • and use it create (definedBy) a module M(F[A], F[B]... F[Z]),
  • then use it to create (createInjector) injector I(F[A], F[B]... F[Z])
  • use injector to get future (completedFrom) module F[M(A, B... Z)]
  • when future is fulfilled, you create injector I(A, B... Z) from the dereferenced module.

Builder was introduced to somewhat simplify composition of eventual provider modules.

// Here's equivalent to the example above
Injector resulting = new EventualModules.Builder()
    .add(new Providers())
    .joinInjector();

// Other builder methods:
//  .skipFailed()
//  .executor(Executor)
//  .toFuture()

The alternative to the solution would be to use plain composition of futures. But even with java 8 lambdas, it's still might be cumbersome to reason about complicated chains of transformation. Definitely, this kind of utility might be also be built specifically for Java 8 without using Guice. This is built with Guava's ListenableFuture and not with CompletableFuture, sorry.

Examples

See FutureJection slides and sample "Barbican" project

eventual's People

Contributors

elucash avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.