Skip to content

Commit

Permalink
Replace onComplete with onSuccess + onFailure
Browse files Browse the repository at this point in the history
Simplify the code by replacing onComplete + if-ar.succeeded-else with
onSuccess and onFailure. This avoid the additional nesting of the if-else
clause.

In addition to the verbose exampleFuture1 code show how it can be reduced
to concise but still understandable code.
  • Loading branch information
julianladisch committed Jan 3, 2025
1 parent 3eb4248 commit 0fb18e0
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 82 deletions.
14 changes: 14 additions & 0 deletions vertx-core/src/main/asciidoc/futures.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ You cannot interact directly with the result of a future, instead you need to se
{@link examples.CoreExamples#exampleFuture1}
----

Instead of using `onComplete` with `if (ar.succeeded()) { … } else { … }` you can use the `onSuccess` and `onFailure` handlers:

[source,$lang]
----
{@link examples.CoreExamples#exampleFuture2}
----

Frequently the future variable can be avoided. Often the lambda parameter type is not needed by compiler and code readers, allowing to replace `(FileProps fileProps)` with `fileProps`. In a lambda code block with a single statement the semicolon and the curly braces can be removed. This yields a more concise code:

[source,$lang]
----
{@link examples.CoreExamples#exampleFuture3}
----

[CAUTION]
====
Do not confuse _futures_ with _promises_.
Expand Down
166 changes: 84 additions & 82 deletions vertx-core/src/main/java/examples/CoreExamples.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
* Copyright (c) 2011-2025 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
Expand Down Expand Up @@ -73,19 +73,19 @@ public void example7(Vertx vertx) {
vertx.executeBlocking(() -> {
// Call some blocking API that takes a significant amount of time to return
return someAPI.blockingMethod("hello");
}).onComplete(res -> {
System.out.println("The result is: " + res.result());
});
})
.onSuccess(result -> System.out.println("The result is: " + result))
.onFailure(e -> e.printStackTrace());
}

public void workerExecutor1(Vertx vertx) {
WorkerExecutor executor = vertx.createSharedWorkerExecutor("my-worker-pool");
executor.executeBlocking(() -> {
// Call some blocking API that takes a significant amount of time to return
return someAPI.blockingMethod("hello");
}).onComplete(res -> {
System.out.println("The result is: " + res.result());
});
})
.onSuccess(result -> System.out.println("The result is: " + result))
.onFailure(e -> e.printStackTrace());
}

public void workerExecutor2(WorkerExecutor executor) {
Expand Down Expand Up @@ -127,7 +127,7 @@ public void clusteredVertxBuilder(VertxOptions options, ClusterManager clusterMa
.buildClustered();
}

public void exampleFuture1(Vertx vertx, Handler<HttpServerRequest> requestHandler) {
public void exampleFuture1(Vertx vertx) {
FileSystem fs = vertx.fileSystem();

Future<FileProps> future = fs.props("/my_file.txt");
Expand All @@ -142,6 +142,28 @@ public void exampleFuture1(Vertx vertx, Handler<HttpServerRequest> requestHandle
});
}

public void exampleFuture2(Vertx vertx) {
FileSystem fs = vertx.fileSystem();

Future<FileProps> future = fs.props("/my_file.txt");

future
.onSuccess((FileProps fileProps) -> {
System.out.println("File size = " + fileProps.size());
})
.onFailure((Throwable e) -> {
System.out.println("Failure: " + e.getMessage());
});
}

public void exampleFuture3(Vertx vertx) {
FileSystem fs = vertx.fileSystem();

fs.props("/my_file.txt")
.onSuccess(fileProps -> System.out.println("File size = " + fileProps.size()))
.onFailure(e -> System.out.println("Failure: " + e.getMessage()));
}

public void promiseCallbackOrder(Future<Void> future) {
future.onComplete(ar -> {
// Do something
Expand Down Expand Up @@ -170,61 +192,58 @@ public void exampleFutureComposition1(Vertx vertx) {
});
}

public void exampleFuture2(Vertx vertx, Handler<HttpServerRequest> requestHandler) {
FileSystem fs = vertx.fileSystem();
public void exampleFutureComposition2(Vertx vertx) {

Future<FileProps> future = fs.props("/my_file.txt");
FileSystem fs = vertx.fileSystem();

future.onComplete((AsyncResult<FileProps> ar) -> {
if (ar.succeeded()) {
FileProps props = ar.result();
System.out.println("File size = " + props.size());
} else {
System.out.println("Failure: " + ar.cause().getMessage());
}
});
Future<Void> future = fs
.createFile("/foo")
// When the file is created (fut1), execute this:
.compose(v -> fs.writeFile("/foo", Buffer.buffer()))
// When the file is written (fut2), execute this:
.compose(v -> fs.move("/foo", "/bar"));
}

public void exampleFutureAll1(HttpServer httpServer, NetServer netServer) {
Future<HttpServer> httpServerFuture = httpServer.listen();

Future<NetServer> netServerFuture = netServer.listen();

Future.all(httpServerFuture, netServerFuture).onComplete(ar -> {
if (ar.succeeded()) {
Future.all(httpServerFuture, netServerFuture)
.onSuccess(result -> {
// All servers started
} else {
})
.onFailure(e -> {
// At least one server failed
}
});
});
}

public void exampleFutureAll2(Future<?> future1, Future<?> future2, Future<?> future3) {
Future.all(Arrays.asList(future1, future2, future3));
}

public void exampleFutureAny1(Future<String> future1, Future<String> future2) {
Future.any(future1, future2).onComplete(ar -> {
if (ar.succeeded()) {
Future.any(future1, future2)
.onSuccess(result -> {
// At least one is succeeded
} else {
})
.onFailure(e -> {
// All failed
}
});
});
}

public void exampleFutureAny2(Future<?> f1, Future<?> f2, Future<?> f3) {
Future.any(Arrays.asList(f1, f2, f3));
}

public void exampleFutureJoin1(Future<?> future1, Future<?> future2, Future<?> future3) {
Future.join(future1, future2, future3).onComplete(ar -> {
if (ar.succeeded()) {
Future.join(future1, future2, future3)
.onSuccess(result -> {
// All succeeded
} else {
})
.onFailure(e -> {
// All completed and at least one failed
}
});
});
}

public void exampleFutureJoin2(Future<?> future1, Future<?> future2, Future<?> future3) {
Expand Down Expand Up @@ -286,13 +305,9 @@ public void start(Promise<Void> startPromise) throws Exception {
Future<String> future = bindService();

// Requires to write
future.onComplete(ar -> {
if (ar.succeeded()) {
startPromise.complete();
} else {
startPromise.fail(ar.cause());
}
});
future
.onSuccess(x -> startPromise.complete())
.onFailure(startPromise::fail);

// Or
future
Expand Down Expand Up @@ -337,25 +352,15 @@ public void example9(Vertx vertx) {
public void example10(Vertx vertx) {
vertx
.deployVerticle(new MyOrderProcessorVerticle())
.onComplete(res -> {
if (res.succeeded()) {
System.out.println("Deployment id is: " + res.result());
} else {
System.out.println("Deployment failed!");
}
});
.onSuccess(deploymentId -> System.out.println("Deployment id is: " + deploymentId))
.onFailure(e -> System.out.println("Deployment failed: " + e.getMessage()));
}

public void example11(Vertx vertx, String deploymentID) {
public void example11(Vertx vertx, String deploymentId) {
vertx
.undeploy(deploymentID)
.onComplete(res -> {
if (res.succeeded()) {
System.out.println("Undeployed ok");
} else {
System.out.println("Undeploy failed!");
}
});
.undeploy(deploymentId)
.onSuccess(x -> System.out.println("Undeployed ok"))
.onFailure(e -> System.out.println("Undeploy failed: " + e.getMessage()));
}

public void example12(Vertx vertx) {
Expand Down Expand Up @@ -527,12 +532,11 @@ public void tcpServerWithDomainSockets(Vertx vertx) {
// Handle application
})
.listen(address)
.onComplete(ar -> {
if (ar.succeeded()) {
// Bound to socket
} else {
// Handle failure
}
.onSuccess(theNetServer -> {
// Bound to socket
})
.onFailure(e -> {
// Handle failure
});
}

Expand All @@ -547,12 +551,11 @@ public void httpServerWithDomainSockets(Vertx vertx) {
// Handle application
})
.listen(address)
.onComplete(ar -> {
if (ar.succeeded()) {
// Bound to socket
} else {
// Handle failure
}
.onSuccess(theHttpServer -> {
// Bound to socket
})
.onFailure(e -> {
// Handle failure
});
}

Expand All @@ -565,12 +568,11 @@ public void tcpClientWithDomainSockets(Vertx vertx) {
// Connect to the server
netClient
.connect(addr)
.onComplete(ar -> {
if (ar.succeeded()) {
// Connected
} else {
// Handle failure
}
.onSuccess(netSocket -> {
// Connected
})
.onFailure(e -> {
// Handle failure
});
}

Expand All @@ -586,13 +588,13 @@ public void httpClientWithDomainSockets(Vertx vertx) {
.setHost("localhost")
.setPort(8080)
.setURI("/"))
.compose(request -> request.send().compose(HttpClientResponse::body))
.onComplete(ar -> {
if (ar.succeeded()) {
// Process response
} else {
// Handle failure
}
.compose(request -> request.send())
.compose(HttpClientResponse::body)
.onSuccess(buffer -> {
// Process response
})
.onFailure(e -> {
// Handle failure
});
}
}

0 comments on commit 0fb18e0

Please sign in to comment.