Skip to content

Commit

Permalink
Future improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
vietj committed Apr 14, 2016
1 parent bd1cf03 commit f1be65f
Show file tree
Hide file tree
Showing 9 changed files with 972 additions and 774 deletions.
1,324 changes: 662 additions & 662 deletions src/main/asciidoc/dataobjects.adoc

Large diffs are not rendered by default.

126 changes: 63 additions & 63 deletions src/main/asciidoc/enums.adoc
@@ -1,68 +1,5 @@
= Enums = Enums


[[HttpVersion]]
== HttpVersion

++++
Represents the version of the HTTP protocol.
++++
'''

[cols=">25%,75%"]
[frame="topbot"]
|===
^|Name | Description
|[[HTTP_1_0]]`HTTP_1_0`|-
|[[HTTP_1_1]]`HTTP_1_1`|-
|[[HTTP_2]]`HTTP_2`|-
|===

[[SSLEngine]]
== SSLEngine

++++
The SSL engine implementation to use in a Vert.x server or client.
++++
'''

[cols=">25%,75%"]
[frame="topbot"]
|===
^|Name | Description
|[[JDK]]`JDK`|
+++
Use the engine provided by the JDK.
+++
|[[OPENSSL]]`OPENSSL`|
+++
Use an OpenSSL based engine.
+++
|===

[[HttpMethod]]
== HttpMethod

++++
Represents an HTTP method
++++
'''

[cols=">25%,75%"]
[frame="topbot"]
|===
^|Name | Description
|[[OPTIONS]]`OPTIONS`|-
|[[GET]]`GET`|-
|[[HEAD]]`HEAD`|-
|[[POST]]`POST`|-
|[[PUT]]`PUT`|-
|[[DELETE]]`DELETE`|-
|[[TRACE]]`TRACE`|-
|[[CONNECT]]`CONNECT`|-
|[[PATCH]]`PATCH`|-
|[[UNKNOWN]]`UNKNOWN`|-
|===

[[ClientAuth]] [[ClientAuth]]
== ClientAuth == ClientAuth


Expand Down Expand Up @@ -165,6 +102,47 @@ ID 14, bad timestamp
+++ +++
|=== |===


[[HttpMethod]]
== HttpMethod

++++
Represents an HTTP method
++++
'''

[cols=">25%,75%"]
[frame="topbot"]
|===
^|Name | Description
|[[OPTIONS]]`OPTIONS`|-
|[[GET]]`GET`|-
|[[HEAD]]`HEAD`|-
|[[POST]]`POST`|-
|[[PUT]]`PUT`|-
|[[DELETE]]`DELETE`|-
|[[TRACE]]`TRACE`|-
|[[CONNECT]]`CONNECT`|-
|[[PATCH]]`PATCH`|-
|[[UNKNOWN]]`UNKNOWN`|-
|===

[[HttpVersion]]
== HttpVersion

++++
Represents the version of the HTTP protocol.
++++
'''

[cols=">25%,75%"]
[frame="topbot"]
|===
^|Name | Description
|[[HTTP_1_0]]`HTTP_1_0`|-
|[[HTTP_1_1]]`HTTP_1_1`|-
|[[HTTP_2]]`HTTP_2`|-
|===

[[ReplyFailure]] [[ReplyFailure]]
== ReplyFailure == ReplyFailure


Expand All @@ -191,6 +169,28 @@ The message send failed because the recipient actively sent back a failure (reje
+++ +++
|=== |===


[[SSLEngine]]
== SSLEngine

++++
The SSL engine implementation to use in a Vert.x server or client.
++++
'''

[cols=">25%,75%"]
[frame="topbot"]
|===
^|Name | Description
|[[JDK]]`JDK`|
+++
Use the engine provided by the JDK.
+++
|[[OPENSSL]]`OPENSSL`|
+++
Use an OpenSSL based engine.
+++
|===

[[WebsocketVersion]] [[WebsocketVersion]]
== WebsocketVersion == WebsocketVersion


Expand Down
11 changes: 8 additions & 3 deletions src/main/asciidoc/java/index.adoc
Expand Up @@ -340,13 +340,18 @@ CompositeFuture.any(future1, future2).setHandler(ar -> {
FileSystem fs = vertx.fileSystem(); FileSystem fs = vertx.fileSystem();
Future<Void> fut1 = Future.future(); Future<Void> fut1 = Future.future();
Future<Void> fut2 = Future.future();
fs.createFile("/foo", fut1.completer()); fs.createFile("/foo", fut1.completer());
fut1.compose(v -> { fut1.compose(v -> {
Future<Void> fut2 = Future.future();
fs.writeFile("/foo", Buffer.buffer(), fut2.completer()); fs.writeFile("/foo", Buffer.buffer(), fut2.completer());
}, fut2);
fut2.compose(v -> { // Compose fut1 with fut2
return fut2;
}).compose(v -> {
// Compose fut1 with fut2 and fut3
fs.move("/foo", "/bar", startFuture.completer()); fs.move("/foo", "/bar", startFuture.completer());
}, startFuture); }, startFuture);
---- ----
Expand Down
11 changes: 8 additions & 3 deletions src/main/java/examples/CoreExamples.java
Expand Up @@ -119,13 +119,18 @@ public void exampleFuture3(Vertx vertx, Future<Void> startFuture) {
FileSystem fs = vertx.fileSystem(); FileSystem fs = vertx.fileSystem();


Future<Void> fut1 = Future.future(); Future<Void> fut1 = Future.future();
Future<Void> fut2 = Future.future();


fs.createFile("/foo", fut1.completer()); fs.createFile("/foo", fut1.completer());
fut1.compose(v -> { fut1.compose(v -> {

Future<Void> fut2 = Future.future();
fs.writeFile("/foo", Buffer.buffer(), fut2.completer()); fs.writeFile("/foo", Buffer.buffer(), fut2.completer());
}, fut2);
fut2.compose(v -> { // Compose fut1 with fut2
return fut2;
}).compose(v -> {

// Compose fut1 with fut2 and fut3
fs.move("/foo", "/bar", startFuture.completer()); fs.move("/foo", "/bar", startFuture.completer());
}, startFuture); }, startFuture);
} }
Expand Down
24 changes: 22 additions & 2 deletions src/main/java/io/vertx/core/CompositeFuture.java
Expand Up @@ -16,10 +16,13 @@


package io.vertx.core; package io.vertx.core;


import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.annotations.VertxGen; import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.impl.CompositeFutureImpl; import io.vertx.core.impl.CompositeFutureImpl;


import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function;


/** /**
* The composite future wraps a list of {@link Future futures}, it is useful when several futures * The composite future wraps a list of {@link Future futures}, it is useful when several futures
Expand Down Expand Up @@ -70,7 +73,9 @@ static <T1, T2, T3, T4, T5, T6> CompositeFuture all(Future<T1> f1, Future<T2> f2
} }


/** /**
* Like {@link #all(Future, Future)} but with a list of futures. * Like {@link #all(Future, Future)} but with a list of futures.<p>
*
* When the list is empty, the returned future will be already completed.
*/ */
static CompositeFuture all(List<Future> futures) { static CompositeFuture all(List<Future> futures) {
return CompositeFutureImpl.all(futures.toArray(new Future[futures.size()])); return CompositeFutureImpl.all(futures.toArray(new Future[futures.size()]));
Expand Down Expand Up @@ -116,7 +121,9 @@ static <T1, T2, T3, T4, T5, T6> CompositeFuture any(Future<T1> f1, Future<T2> f2
} }


/** /**
* Like {@link #any(Future, Future)} but with a list of futures. * Like {@link #any(Future, Future)} but with a list of futures.<p>
*
* When the list is empty, the returned future will be already completed.
*/ */
static CompositeFuture any(List<Future> futures) { static CompositeFuture any(List<Future> futures) {
return CompositeFutureImpl.any(futures.toArray(new Future[futures.size()])); return CompositeFutureImpl.any(futures.toArray(new Future[futures.size()]));
Expand Down Expand Up @@ -165,4 +172,17 @@ static CompositeFuture any(List<Future> futures) {
*/ */
int size(); int size();


/**
* @return a list of the current completed values. If one future is not yet resolved or is failed, {@code} null
* will be used
*/
@GenIgnore
default <T> List<T> list() {
int size = size();
ArrayList<T> list = new ArrayList<>(size);
for (int index = 0;index < size;index++) {
list.add(result(index));
}
return list;
}
} }
110 changes: 102 additions & 8 deletions src/main/java/io/vertx/core/Future.java
Expand Up @@ -171,30 +171,124 @@ static <T> Future<T> failedFuture(String failureMessage) {
boolean failed(); boolean failed();


/** /**
* Compose this future with another future. * Compose this future with a provided {@code next} future.<p>
* *
* When this future succeeds, the handler will be called with the value. * When this future succeeds, the {@code handler} will be called with the completed value, this handler
* should complete the next future.<p>
* *
* When this future fails, the failure will be propagated to the {@code next} future. * If the {@code handler} throws an exception, the returned future will be failed with this exception.<p>
*
* When this future fails, the failure will be propagated to the {@code next} future and the {@code handler}
* will not be called.
* *
* @param handler the handler * @param handler the handler
* @param next the next future * @param composed the composed future
* @return the composed future, used for chaining
*/ */
default <U> void compose(Handler<T> handler, Future<U> next) { default <U> Future<U> compose(Handler<T> handler, Future<U> composed) {
setHandler(ar -> { setHandler(ar -> {
if (ar.succeeded()) { if (ar.succeeded()) {
try { try {
handler.handle(ar.result()); handler.handle(ar.result());
} catch (Throwable err) { } catch (Throwable err) {
if (next.isComplete()) { if (composed.isComplete()) {
throw err; throw err;
} }
next.fail(err); composed.fail(err);
}
} else {
composed.fail(ar.cause());
}
});
return composed;
}

/**
* Compose this future with a {@code mapper} function.<p>
*
* When this future succeeds, the {@code mapper} will be called with the completed value and this mapper
* returns a future. This returned future completion will trigger the future returned by this method call.<p>
*
* If the {@code mapper} throws an exception, the returned future will be failed with this exception.<p>
*
* When this future fails, the failure will be propagated to the returned future and the {@code mapper}
* will not be called.
*
* @param mapper the mapper function
* @return the composed future
*/
default <U> Future<U> compose(Function<T, Future<U>> mapper) {
Future<U> ret = Future.future();
setHandler(ar -> {
if (ar.succeeded()) {
Future<U> apply;
try {
apply = mapper.apply(ar.result());
} catch (Throwable e) {
ret.fail(e);
return;
} }
apply.setHandler(ret.completer());
} else {
ret.fail(ar.cause());
}
});
return ret;
}

/**
* Apply a {@code mapper} function on this future.<p>
*
* When this future succeeds, the {@code mapper} will be called with the completed value and this mapper
* returns a value. This value will complete the future returned by this method call.<p>
*
* If the {@code mapper} throws an exception, the returned future will be failed with this exception.<p>
*
* When this future fails, the failure will be propagated to the returned future and the {@code mapper}
* will not be called.
*
* @param mapper the mapper function
* @return the mapped future
*/
default <U> Future<U> map(Function<T, U> mapper) {
Future<U> ret = Future.future();
setHandler(ar -> {
if (ar.succeeded()) {
U mapped;
try {
mapped = mapper.apply(ar.result());
} catch (Throwable e) {
ret.fail(e);
return;
}
ret.complete(mapped);
} else {
ret.fail(ar.cause());
}
});
return ret;
}

/**
* Map the result of a future to a specific {@code value}.<p>
*
* When this future succeeds, this {@code value} will complete the future returned by this method call.<p>
*
* When this future fails, the failure will be propagated to the returned future.
*
* @param value the value that eventually completes the mapped future
* @return the mapped future
*/
default <V> Future<V> map(V value) {
Future<V> ret = Future.future();
setHandler(ar -> {
if (ar.succeeded()) {
ret.complete(value);
} else { } else {
next.fail(ar.cause()); ret.fail(ar.cause());
} }
}); });
return ret;
} }


/** /**
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/io/vertx/core/impl/CompositeFutureImpl.java
Expand Up @@ -51,6 +51,9 @@ public static CompositeFuture all(Future<?>... results) {
} }
}); });
} }
if (results.length == 0) {
composite.setSucceeded();
}
return composite; return composite;
} }


Expand Down Expand Up @@ -79,6 +82,9 @@ public static CompositeFuture any(Future<?>... results) {
} }
}); });
} }
if (results.length == 0) {
composite.setSucceeded();
}
return composite; return composite;
} }


Expand Down

0 comments on commit f1be65f

Please sign in to comment.