2011-12-19 11:07:59 +01:00
|
|
|
/**
|
2012-01-19 18:21:06 +01:00
|
|
|
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
2011-12-19 11:07:59 +01:00
|
|
|
*/
|
2012-05-22 11:37:09 +02:00
|
|
|
package docs.future;
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
//#imports1
|
2012-01-26 14:15:25 +01:00
|
|
|
import akka.dispatch.*;
|
2012-07-06 17:04:04 +02:00
|
|
|
import scala.concurrent.ExecutionContext;
|
|
|
|
|
import scala.concurrent.Future;
|
2012-06-29 16:40:36 +02:00
|
|
|
import scala.concurrent.Await;
|
2011-12-15 22:31:12 +01:00
|
|
|
import akka.util.Timeout;
|
|
|
|
|
//#imports1
|
|
|
|
|
|
|
|
|
|
//#imports2
|
2012-06-29 13:33:20 +02:00
|
|
|
import scala.concurrent.util.Duration;
|
2011-12-15 22:31:12 +01:00
|
|
|
import akka.japi.Function;
|
|
|
|
|
import java.util.concurrent.Callable;
|
|
|
|
|
import static akka.dispatch.Futures.future;
|
|
|
|
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
|
|
|
|
//#imports2
|
|
|
|
|
|
|
|
|
|
//#imports3
|
|
|
|
|
import static akka.dispatch.Futures.sequence;
|
|
|
|
|
//#imports3
|
|
|
|
|
|
|
|
|
|
//#imports4
|
|
|
|
|
import static akka.dispatch.Futures.traverse;
|
|
|
|
|
//#imports4
|
|
|
|
|
|
|
|
|
|
//#imports5
|
|
|
|
|
import akka.japi.Function2;
|
|
|
|
|
import static akka.dispatch.Futures.fold;
|
|
|
|
|
//#imports5
|
|
|
|
|
|
|
|
|
|
//#imports6
|
|
|
|
|
import static akka.dispatch.Futures.reduce;
|
|
|
|
|
//#imports6
|
|
|
|
|
|
2012-02-20 15:43:17 +01:00
|
|
|
//#imports7
|
2012-06-29 16:40:36 +02:00
|
|
|
import scala.concurrent.ExecutionContext;
|
|
|
|
|
import scala.concurrent.ExecutionContext$;
|
2012-02-20 15:43:17 +01:00
|
|
|
//#imports7
|
|
|
|
|
|
2012-08-20 19:49:01 +02:00
|
|
|
//#imports8
|
|
|
|
|
import static akka.pattern.Patterns.after;
|
|
|
|
|
//#imports8
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.List;
|
2012-02-20 15:43:17 +01:00
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
|
import java.util.concurrent.Executors;
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
import org.junit.After;
|
|
|
|
|
import org.junit.Before;
|
|
|
|
|
import org.junit.Test;
|
|
|
|
|
|
|
|
|
|
import akka.testkit.AkkaSpec;
|
|
|
|
|
import akka.actor.Status.Failure;
|
|
|
|
|
import akka.actor.ActorSystem;
|
|
|
|
|
import akka.actor.UntypedActor;
|
|
|
|
|
import akka.actor.ActorRef;
|
|
|
|
|
import akka.actor.Props;
|
2012-01-18 10:18:51 +01:00
|
|
|
import akka.pattern.Patterns;
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
import static org.junit.Assert.*;
|
|
|
|
|
|
|
|
|
|
public class FutureDocTestBase {
|
|
|
|
|
|
|
|
|
|
ActorSystem system;
|
|
|
|
|
|
|
|
|
|
@Before
|
|
|
|
|
public void setUp() {
|
|
|
|
|
system = ActorSystem.create("MySystem", AkkaSpec.testConf());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@After
|
|
|
|
|
public void tearDown() {
|
|
|
|
|
system.shutdown();
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-29 16:40:36 +02:00
|
|
|
@SuppressWarnings("unchecked") @Test public void useCustomExecutionContext() throws Exception {
|
2012-02-20 15:43:17 +01:00
|
|
|
ExecutorService yourExecutorServiceGoesHere = Executors.newSingleThreadExecutor();
|
|
|
|
|
//#diy-execution-context
|
2012-06-29 16:40:36 +02:00
|
|
|
ExecutionContext ec =
|
2012-08-02 11:40:27 +02:00
|
|
|
ExecutionContexts.fromExecutorService(yourExecutorServiceGoesHere);
|
2012-02-20 15:43:17 +01:00
|
|
|
|
|
|
|
|
//Use ec with your Futures
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> f1 = Futures.successful("foo");
|
2012-02-20 15:43:17 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
// Then you shut down the ExecutorService at the end of your application.
|
2012-06-29 16:40:36 +02:00
|
|
|
yourExecutorServiceGoesHere.shutdown();
|
2012-02-20 15:43:17 +01:00
|
|
|
//#diy-execution-context
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useBlockingFromActor() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
ActorRef actor = system.actorOf(new Props(MyActor.class));
|
|
|
|
|
String msg = "hello";
|
|
|
|
|
//#ask-blocking
|
2012-09-14 10:08:40 +02:00
|
|
|
Timeout timeout = new Timeout(Duration.create(5, "seconds"));
|
2011-12-31 17:42:13 -08:00
|
|
|
Future<Object> future = Patterns.ask(actor, msg, timeout);
|
2011-12-15 22:31:12 +01:00
|
|
|
String result = (String) Await.result(future, timeout.duration());
|
|
|
|
|
//#ask-blocking
|
|
|
|
|
assertEquals("HELLO", result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useFutureEval() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
//#future-eval
|
|
|
|
|
Future<String> f = future(new Callable<String>() {
|
|
|
|
|
public String call() {
|
|
|
|
|
return "Hello" + "World";
|
|
|
|
|
}
|
|
|
|
|
}, system.dispatcher());
|
|
|
|
|
String result = (String) Await.result(f, Duration.create(1, SECONDS));
|
|
|
|
|
//#future-eval
|
|
|
|
|
assertEquals("HelloWorld", result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useMap() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
//#map
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
Future<String> f1 = future(new Callable<String>() {
|
|
|
|
|
public String call() {
|
|
|
|
|
return "Hello" + "World";
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
2012-01-25 22:36:03 +01:00
|
|
|
Future<Integer> f2 = f1.map(new Mapper<String, Integer>() {
|
2011-12-15 22:31:12 +01:00
|
|
|
public Integer apply(String s) {
|
|
|
|
|
return s.length();
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
int result = Await.result(f2, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals(10, result);
|
|
|
|
|
//#map
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void useMap2() throws Exception {
|
|
|
|
|
//#map2
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
Future<String> f1 = future(new Callable<String>() {
|
|
|
|
|
public String call() throws Exception {
|
|
|
|
|
Thread.sleep(100);
|
|
|
|
|
return "Hello" + "World";
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
2012-01-25 22:36:03 +01:00
|
|
|
Future<Integer> f2 = f1.map(new Mapper<String, Integer>() {
|
2011-12-15 22:31:12 +01:00
|
|
|
public Integer apply(String s) {
|
|
|
|
|
return s.length();
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
//#map2
|
|
|
|
|
int result = Await.result(f2, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals(10, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void useMap3() throws Exception {
|
|
|
|
|
//#map3
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
Future<String> f1 = future(new Callable<String>() {
|
|
|
|
|
public String call() {
|
|
|
|
|
return "Hello" + "World";
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
Thread.sleep(100);
|
|
|
|
|
|
2012-01-25 22:36:03 +01:00
|
|
|
Future<Integer> f2 = f1.map(new Mapper<String, Integer>() {
|
2011-12-15 22:31:12 +01:00
|
|
|
public Integer apply(String s) {
|
|
|
|
|
return s.length();
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
//#map3
|
|
|
|
|
int result = Await.result(f2, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals(10, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useFlatMap() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
//#flat-map
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
Future<String> f1 = future(new Callable<String>() {
|
|
|
|
|
public String call() {
|
|
|
|
|
return "Hello" + "World";
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
2012-01-25 22:36:03 +01:00
|
|
|
Future<Integer> f2 = f1.flatMap(new Mapper<String, Future<Integer>>() {
|
2011-12-15 22:31:12 +01:00
|
|
|
public Future<Integer> apply(final String s) {
|
|
|
|
|
return future(new Callable<Integer>() {
|
|
|
|
|
public Integer call() {
|
|
|
|
|
return s.length();
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
//#flat-map
|
|
|
|
|
int result = Await.result(f2, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals(10, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useSequence() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
List<Future<Integer>> source = new ArrayList<Future<Integer>>();
|
2012-07-22 21:40:09 +02:00
|
|
|
source.add(Futures.successful(1));
|
|
|
|
|
source.add(Futures.successful(2));
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
//#sequence
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2011-12-15 22:31:12 +01:00
|
|
|
//Some source generating a sequence of Future<Integer>:s
|
|
|
|
|
Iterable<Future<Integer>> listOfFutureInts = source;
|
|
|
|
|
|
|
|
|
|
// now we have a Future[Iterable[Integer]]
|
2012-07-06 17:04:04 +02:00
|
|
|
Future<Iterable<Integer>> futureListOfInts = sequence(listOfFutureInts, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
// Find the sum of the odd numbers
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<Long> futureSum = futureListOfInts.map(
|
|
|
|
|
new Mapper<Iterable<Integer>, Long>() {
|
|
|
|
|
public Long apply(Iterable<Integer> ints) {
|
|
|
|
|
long sum = 0;
|
|
|
|
|
for (Integer i : ints)
|
|
|
|
|
sum += i;
|
|
|
|
|
return sum;
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
long result = Await.result(futureSum, Duration.create(1, SECONDS));
|
|
|
|
|
//#sequence
|
|
|
|
|
assertEquals(3L, result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useTraverse() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
//#traverse
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2011-12-15 22:31:12 +01:00
|
|
|
//Just a sequence of Strings
|
|
|
|
|
Iterable<String> listStrings = Arrays.asList("a", "b", "c");
|
|
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<Iterable<String>> futureResult = traverse(listStrings,
|
|
|
|
|
new Function<String, Future<String>>() {
|
|
|
|
|
public Future<String> apply(final String r) {
|
|
|
|
|
return future(new Callable<String>() {
|
|
|
|
|
public String call() {
|
|
|
|
|
return r.toUpperCase();
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
|
|
|
|
//Returns the sequence of strings as upper case
|
2012-02-10 16:02:37 +01:00
|
|
|
Iterable<String> result = Await.result(futureResult, Duration.create(1, SECONDS));
|
2011-12-15 22:31:12 +01:00
|
|
|
assertEquals(Arrays.asList("A", "B", "C"), result);
|
|
|
|
|
//#traverse
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useFold() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
List<Future<String>> source = new ArrayList<Future<String>>();
|
2012-07-22 21:40:09 +02:00
|
|
|
source.add(Futures.successful("a"));
|
|
|
|
|
source.add(Futures.successful("b"));
|
2011-12-15 22:31:12 +01:00
|
|
|
//#fold
|
|
|
|
|
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
//A sequence of Futures, in this case Strings
|
|
|
|
|
Iterable<Future<String>> futures = source;
|
|
|
|
|
|
|
|
|
|
//Start value is the empty string
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<String> resultFuture = fold("", futures,
|
|
|
|
|
new Function2<String, String, String>() {
|
|
|
|
|
public String apply(String r, String t) {
|
|
|
|
|
return r + t; //Just concatenate
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
String result = Await.result(resultFuture, Duration.create(1, SECONDS));
|
|
|
|
|
//#fold
|
|
|
|
|
|
|
|
|
|
assertEquals("ab", result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useReduce() throws Exception {
|
2011-12-15 22:31:12 +01:00
|
|
|
List<Future<String>> source = new ArrayList<Future<String>>();
|
2012-07-22 21:40:09 +02:00
|
|
|
source.add(Futures.successful("a"));
|
|
|
|
|
source.add(Futures.successful("b"));
|
2011-12-15 22:31:12 +01:00
|
|
|
//#reduce
|
|
|
|
|
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2011-12-15 22:31:12 +01:00
|
|
|
//A sequence of Futures, in this case Strings
|
|
|
|
|
Iterable<Future<String>> futures = source;
|
|
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<Object> resultFuture = reduce(futures,
|
|
|
|
|
new Function2<Object, String, Object>() {
|
|
|
|
|
public Object apply(Object r, String t) {
|
|
|
|
|
return r + t; //Just concatenate
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
2011-12-15 22:31:12 +01:00
|
|
|
|
2012-01-19 17:47:58 +01:00
|
|
|
Object result = Await.result(resultFuture, Duration.create(1, SECONDS));
|
2011-12-15 22:31:12 +01:00
|
|
|
//#reduce
|
|
|
|
|
|
|
|
|
|
assertEquals("ab", result);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useSuccessfulAndFailed() throws Exception {
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2012-01-24 16:31:20 +01:00
|
|
|
//#successful
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> future = Futures.successful("Yay!");
|
2012-01-24 16:31:20 +01:00
|
|
|
//#successful
|
|
|
|
|
//#failed
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<String> otherFuture = Futures.failed(
|
|
|
|
|
new IllegalArgumentException("Bang!"));
|
2012-01-24 16:31:20 +01:00
|
|
|
//#failed
|
|
|
|
|
Object result = Await.result(future, Duration.create(1, SECONDS));
|
2012-02-10 16:02:37 +01:00
|
|
|
assertEquals("Yay!", result);
|
2012-09-26 10:56:25 +02:00
|
|
|
Throwable result2 = Await.result(otherFuture.failed(),
|
|
|
|
|
Duration.create(1, SECONDS));
|
2012-02-10 16:02:37 +01:00
|
|
|
assertEquals("Bang!", result2.getMessage());
|
2012-01-24 16:31:20 +01:00
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useFilter() throws Exception {
|
2012-02-10 16:02:37 +01:00
|
|
|
//#filter
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<Integer> future1 = Futures.successful(4);
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<Integer> successfulFilter = future1.filter(Filter.filterOf(
|
|
|
|
|
new Function<Integer, Boolean>() {
|
|
|
|
|
public Boolean apply(Integer i) {
|
|
|
|
|
return i % 2 == 0;
|
|
|
|
|
}
|
|
|
|
|
}), ec);
|
2012-01-24 16:31:20 +01:00
|
|
|
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<Integer> failedFilter = future1.filter(Filter.filterOf(
|
|
|
|
|
new Function<Integer, Boolean>() {
|
|
|
|
|
public Boolean apply(Integer i) {
|
|
|
|
|
return i % 2 != 0;
|
|
|
|
|
}
|
|
|
|
|
}), ec);
|
2012-01-24 16:31:20 +01:00
|
|
|
//When filter fails, the returned Future will be failed with a scala.MatchError
|
|
|
|
|
//#filter
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-31 16:00:46 +01:00
|
|
|
public void sendToTheInternetz(String s) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void sendToIssueTracker(Throwable t) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
|
|
|
|
public void useAndThen() {
|
2012-01-31 16:00:46 +01:00
|
|
|
//#and-then
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<String> future1 = Futures.successful("value").andThen(
|
|
|
|
|
new OnComplete<String>() {
|
2012-02-20 15:43:17 +01:00
|
|
|
public void onComplete(Throwable failure, String result) {
|
2012-09-26 10:56:25 +02:00
|
|
|
if (failure != null)
|
|
|
|
|
sendToIssueTracker(failure);
|
2012-02-20 15:43:17 +01:00
|
|
|
}
|
2012-09-26 10:56:25 +02:00
|
|
|
}, ec).andThen(new OnComplete<String>() {
|
2012-02-10 16:02:37 +01:00
|
|
|
public void onComplete(Throwable failure, String result) {
|
|
|
|
|
if (result != null)
|
|
|
|
|
sendToTheInternetz(result);
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-01-31 16:00:46 +01:00
|
|
|
//#and-then
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useRecover() throws Exception {
|
2012-01-31 16:00:46 +01:00
|
|
|
//#recover
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2012-01-31 16:00:46 +01:00
|
|
|
Future<Integer> future = future(new Callable<Integer>() {
|
|
|
|
|
public Integer call() {
|
|
|
|
|
return 1 / 0;
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec).recover(new Recover<Integer>() {
|
2012-02-10 16:02:37 +01:00
|
|
|
public Integer recover(Throwable problem) throws Throwable {
|
|
|
|
|
if (problem instanceof ArithmeticException)
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
throw problem;
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-01-31 16:00:46 +01:00
|
|
|
int result = Await.result(future, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals(result, 0);
|
|
|
|
|
//#recover
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useTryRecover() throws Exception {
|
2012-01-31 16:00:46 +01:00
|
|
|
//#try-recover
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2012-01-31 16:00:46 +01:00
|
|
|
Future<Integer> future = future(new Callable<Integer>() {
|
|
|
|
|
public Integer call() {
|
|
|
|
|
return 1 / 0;
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec).recoverWith(new Recover<Future<Integer>>() {
|
2012-02-10 16:02:37 +01:00
|
|
|
public Future<Integer> recover(Throwable problem) throws Throwable {
|
|
|
|
|
if (problem instanceof ArithmeticException) {
|
|
|
|
|
return future(new Callable<Integer>() {
|
|
|
|
|
public Integer call() {
|
|
|
|
|
return 0;
|
2012-01-31 16:00:46 +01:00
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-02-10 16:02:37 +01:00
|
|
|
} else
|
|
|
|
|
throw problem;
|
|
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-01-31 16:00:46 +01:00
|
|
|
int result = Await.result(future, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals(result, 0);
|
|
|
|
|
//#try-recover
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useOnSuccessOnFailureAndOnComplete() throws Exception {
|
2012-02-10 16:02:37 +01:00
|
|
|
{
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> future = Futures.successful("foo");
|
2012-02-10 08:20:36 +01:00
|
|
|
|
2012-01-24 16:31:20 +01:00
|
|
|
//#onSuccess
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2012-01-25 22:36:03 +01:00
|
|
|
future.onSuccess(new OnSuccess<String>() {
|
2012-02-10 16:02:37 +01:00
|
|
|
public void onSuccess(String result) {
|
|
|
|
|
if ("bar" == result) {
|
|
|
|
|
//Do something if it resulted in "bar"
|
|
|
|
|
} else {
|
|
|
|
|
//Do something if it was some other String
|
2012-01-24 16:31:20 +01:00
|
|
|
}
|
2012-02-10 16:02:37 +01:00
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-01-24 16:31:20 +01:00
|
|
|
//#onSuccess
|
2012-02-10 16:02:37 +01:00
|
|
|
}
|
|
|
|
|
{
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> future = Futures.failed(new IllegalStateException("OHNOES"));
|
2012-02-10 16:02:37 +01:00
|
|
|
//#onFailure
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
future.onFailure(new OnFailure() {
|
2012-01-25 22:36:03 +01:00
|
|
|
public void onFailure(Throwable failure) {
|
2012-02-10 16:02:37 +01:00
|
|
|
if (failure instanceof IllegalStateException) {
|
|
|
|
|
//Do something if it was this particular failure
|
|
|
|
|
} else {
|
|
|
|
|
//Do something if it was some other failure
|
|
|
|
|
}
|
2012-01-24 16:31:20 +01:00
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-01-24 16:31:20 +01:00
|
|
|
//#onFailure
|
2012-02-10 16:02:37 +01:00
|
|
|
}
|
|
|
|
|
{
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> future = Futures.successful("foo");
|
2012-02-10 16:02:37 +01:00
|
|
|
//#onComplete
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
future.onComplete(new OnComplete<String>() {
|
2012-02-20 15:43:17 +01:00
|
|
|
public void onComplete(Throwable failure, String result) {
|
|
|
|
|
if (failure != null) {
|
|
|
|
|
//We got a failure, handle it here
|
|
|
|
|
} else {
|
|
|
|
|
// We got a result, do something with it
|
|
|
|
|
}
|
2012-02-10 16:02:37 +01:00
|
|
|
}
|
2012-07-06 17:04:04 +02:00
|
|
|
}, ec);
|
2012-02-10 16:02:37 +01:00
|
|
|
//#onComplete
|
|
|
|
|
}
|
2012-01-24 16:31:20 +01:00
|
|
|
}
|
|
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
@Test
|
2012-02-16 12:31:49 +01:00
|
|
|
public void useOrAndZip() throws Exception {
|
2012-01-24 16:31:20 +01:00
|
|
|
{
|
2012-02-10 16:02:37 +01:00
|
|
|
//#zip
|
2012-07-06 17:04:04 +02:00
|
|
|
final ExecutionContext ec = system.dispatcher();
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> future1 = Futures.successful("foo");
|
|
|
|
|
Future<String> future2 = Futures.successful("bar");
|
2012-09-26 10:56:25 +02:00
|
|
|
Future<String> future3 = future1.zip(future2).map(
|
|
|
|
|
new Mapper<scala.Tuple2<String, String>, String>() {
|
|
|
|
|
public String apply(scala.Tuple2<String, String> zipped) {
|
|
|
|
|
return zipped._1() + " " + zipped._2();
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
2012-01-24 16:31:20 +01:00
|
|
|
|
2012-02-10 16:02:37 +01:00
|
|
|
String result = Await.result(future3, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals("foo bar", result);
|
|
|
|
|
//#zip
|
2012-01-24 16:31:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
2012-02-10 16:02:37 +01:00
|
|
|
//#fallback-to
|
2012-07-22 21:40:09 +02:00
|
|
|
Future<String> future1 = Futures.failed(new IllegalStateException("OHNOES1"));
|
|
|
|
|
Future<String> future2 = Futures.failed(new IllegalStateException("OHNOES2"));
|
|
|
|
|
Future<String> future3 = Futures.successful("bar");
|
2012-09-26 10:56:25 +02:00
|
|
|
// Will have "bar" in this case
|
|
|
|
|
Future<String> future4 = future1.fallbackTo(future2).fallbackTo(future3);
|
2012-02-10 16:02:37 +01:00
|
|
|
String result = Await.result(future4, Duration.create(1, SECONDS));
|
|
|
|
|
assertEquals("bar", result);
|
|
|
|
|
//#fallback-to
|
2012-01-24 16:31:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-20 19:49:01 +02:00
|
|
|
@Test(expected = IllegalStateException.class)
|
|
|
|
|
public void useAfter() throws Exception {
|
|
|
|
|
//#after
|
|
|
|
|
final ExecutionContext ec = system.dispatcher();
|
|
|
|
|
Future<String> failExc = Futures.failed(new IllegalStateException("OHNOES1"));
|
2012-09-18 09:58:30 +02:00
|
|
|
Future<String> delayed = Patterns.after(Duration.create(500, "millis"),
|
2012-08-20 19:49:01 +02:00
|
|
|
system.scheduler(), ec, failExc);
|
|
|
|
|
Future<String> future = future(new Callable<String>() {
|
|
|
|
|
public String call() throws InterruptedException {
|
|
|
|
|
Thread.sleep(1000);
|
|
|
|
|
return "foo";
|
|
|
|
|
}
|
|
|
|
|
}, ec);
|
2012-08-21 09:01:04 +02:00
|
|
|
Future<String> result = future.either(delayed);
|
2012-08-20 19:49:01 +02:00
|
|
|
//#after
|
|
|
|
|
Await.result(result, Duration.create(2, SECONDS));
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-15 22:31:12 +01:00
|
|
|
public static class MyActor extends UntypedActor {
|
|
|
|
|
public void onReceive(Object message) {
|
|
|
|
|
if (message instanceof String) {
|
2012-09-19 23:55:53 +02:00
|
|
|
getSender().tell(((String) message).toUpperCase(), getSelf());
|
2011-12-15 22:31:12 +01:00
|
|
|
} else if (message instanceof Integer) {
|
|
|
|
|
int i = ((Integer) message).intValue();
|
|
|
|
|
if (i < 0) {
|
2012-09-19 23:55:53 +02:00
|
|
|
getSender().tell(new Failure(new ArithmeticException("Negative values not supported")), getSelf());
|
2011-12-15 22:31:12 +01:00
|
|
|
} else {
|
2012-09-19 23:55:53 +02:00
|
|
|
getSender().tell(i, getSelf());
|
2011-12-15 22:31:12 +01:00
|
|
|
}
|
2011-12-29 20:49:26 +01:00
|
|
|
} else {
|
|
|
|
|
unhandled(message);
|
2011-12-15 22:31:12 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|