use of java.util.concurrent.CompletableFuture in project vert.x by eclipse.
the class VertxTestBase method createWorker.
/**
* Create a worker verticle for the current Vert.x and return its context.
*
* @return the context
* @throws Exception anything preventing the creation of the worker
*/
protected Context createWorker() throws Exception {
CompletableFuture<Context> fut = new CompletableFuture<>();
vertx.deployVerticle(new AbstractVerticle() {
@Override
public void start() throws Exception {
fut.complete(context);
}
}, new DeploymentOptions().setWorker(true), ar -> {
if (ar.failed()) {
fut.completeExceptionally(ar.cause());
}
});
return fut.get();
}
use of java.util.concurrent.CompletableFuture in project vert.x by eclipse.
the class HttpMetricsTest method testHttpClientLifecycle.
private void testHttpClientLifecycle(HttpVersion protocol) throws Exception {
HttpServer server = vertx.createHttpServer();
CountDownLatch requestBeginLatch = new CountDownLatch(1);
CountDownLatch requestBodyLatch = new CountDownLatch(1);
CountDownLatch requestEndLatch = new CountDownLatch(1);
CompletableFuture<Void> beginResponse = new CompletableFuture<>();
CompletableFuture<Void> endResponse = new CompletableFuture<>();
server.requestHandler(req -> {
assertEquals(protocol, req.version());
requestBeginLatch.countDown();
req.handler(buff -> {
requestBodyLatch.countDown();
});
req.endHandler(v -> {
requestEndLatch.countDown();
});
Context ctx = vertx.getOrCreateContext();
beginResponse.thenAccept(v1 -> {
ctx.runOnContext(v2 -> {
req.response().setChunked(true).write(TestUtils.randomAlphaString(1024));
});
});
endResponse.thenAccept(v1 -> {
ctx.runOnContext(v2 -> {
req.response().end();
});
});
});
CountDownLatch listenLatch = new CountDownLatch(1);
server.listen(8080, "localhost", onSuccess(s -> {
listenLatch.countDown();
}));
awaitLatch(listenLatch);
HttpClient client = vertx.createHttpClient(new HttpClientOptions().setProtocolVersion(protocol));
FakeHttpClientMetrics clientMetrics = FakeMetricsBase.getMetrics(client);
CountDownLatch responseBeginLatch = new CountDownLatch(1);
CountDownLatch responseEndLatch = new CountDownLatch(1);
HttpClientRequest req = client.post(8080, "localhost", "/somepath", resp -> {
responseBeginLatch.countDown();
resp.endHandler(v -> {
responseEndLatch.countDown();
});
}).setChunked(true);
req.sendHead();
awaitLatch(requestBeginLatch);
HttpClientMetric reqMetric = clientMetrics.getMetric(req);
assertEquals(0, reqMetric.requestEnded.get());
assertEquals(0, reqMetric.responseBegin.get());
req.write(TestUtils.randomAlphaString(1024));
awaitLatch(requestBodyLatch);
assertEquals(0, reqMetric.requestEnded.get());
assertEquals(0, reqMetric.responseBegin.get());
req.end();
awaitLatch(requestEndLatch);
assertEquals(1, reqMetric.requestEnded.get());
assertEquals(0, reqMetric.responseBegin.get());
beginResponse.complete(null);
awaitLatch(responseBeginLatch);
assertEquals(1, reqMetric.requestEnded.get());
assertEquals(1, reqMetric.responseBegin.get());
endResponse.complete(null);
awaitLatch(responseEndLatch);
assertNull(clientMetrics.getMetric(req));
assertEquals(1, reqMetric.requestEnded.get());
assertEquals(1, reqMetric.responseBegin.get());
}
use of java.util.concurrent.CompletableFuture in project vert.x by eclipse.
the class HttpTest method testDeliverPausedBufferWhenResume.
@Test
public void testDeliverPausedBufferWhenResume() throws Exception {
Buffer data = TestUtils.randomBuffer(20);
int num = 10;
waitFor(num);
List<CompletableFuture<Void>> resumes = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < num; i++) {
resumes.add(new CompletableFuture<>());
}
server.requestHandler(req -> {
int idx = Integer.parseInt(req.path().substring(1));
HttpServerResponse resp = req.response();
resumes.get(idx).thenAccept(v -> {
resp.end();
});
resp.setChunked(true).write(data);
});
startServer();
client.close();
client = vertx.createHttpClient(createBaseClientOptions().setMaxPoolSize(1).setKeepAlive(true));
for (int i = 0; i < num; i++) {
int idx = i;
client.request(HttpMethod.GET, DEFAULT_HTTP_PORT, DEFAULT_HTTP_HOST, "/" + i, resp -> {
Buffer body = Buffer.buffer();
resp.handler(buff -> {
resumes.get(idx).complete(null);
body.appendBuffer(buff);
});
resp.endHandler(v -> {
assertEquals(data, body);
complete();
});
resp.pause();
vertx.setTimer(10, id -> {
resp.resume();
});
}).end();
}
await();
}
use of java.util.concurrent.CompletableFuture in project elasticsearch by elastic.
the class Cache method computeIfAbsent.
/**
* If the specified key is not already associated with a value (or is mapped to null), attempts to compute its
* value using the given mapping function and enters it into this map unless null. The load method for a given key
* will be invoked at most once.
*
* Use of different {@link CacheLoader} implementations on the same key concurrently may result in only the first
* loader function being called and the second will be returned the result provided by the first including any exceptions
* thrown during the execution of the first.
*
* @param key the key whose associated value is to be returned or computed for if non-existent
* @param loader the function to compute a value given a key
* @return the current (existing or computed) non-null value associated with the specified key
* @throws ExecutionException thrown if loader throws an exception or returns a null value
*/
public V computeIfAbsent(K key, CacheLoader<K, V> loader) throws ExecutionException {
long now = now();
V value = get(key, now);
if (value == null) {
// we need to synchronize loading of a value for a given key; however, holding the segment lock while
// invoking load can lead to deadlock against another thread due to dependent key loading; therefore, we
// need a mechanism to ensure that load is invoked at most once, but we are not invoking load while holding
// the segment lock; to do this, we atomically put a future in the map that can load the value, and then
// get the value from this future on the thread that won the race to place the future into the segment map
CacheSegment<K, V> segment = getCacheSegment(key);
CompletableFuture<Entry<K, V>> future;
CompletableFuture<Entry<K, V>> completableFuture = new CompletableFuture<>();
try (ReleasableLock ignored = segment.writeLock.acquire()) {
future = segment.map.putIfAbsent(key, completableFuture);
}
BiFunction<? super Entry<K, V>, Throwable, ? extends V> handler = (ok, ex) -> {
if (ok != null) {
try (ReleasableLock ignored = lruLock.acquire()) {
promote(ok, now);
}
return ok.value;
} else {
try (ReleasableLock ignored = segment.writeLock.acquire()) {
CompletableFuture<Entry<K, V>> sanity = segment.map.get(key);
if (sanity != null && sanity.isCompletedExceptionally()) {
segment.map.remove(key);
}
}
return null;
}
};
CompletableFuture<V> completableValue;
if (future == null) {
future = completableFuture;
completableValue = future.handle(handler);
V loaded;
try {
loaded = loader.load(key);
} catch (Exception e) {
future.completeExceptionally(e);
throw new ExecutionException(e);
}
if (loaded == null) {
NullPointerException npe = new NullPointerException("loader returned a null value");
future.completeExceptionally(npe);
throw new ExecutionException(npe);
} else {
future.complete(new Entry<>(key, loaded, now));
}
} else {
completableValue = future.handle(handler);
}
try {
value = completableValue.get();
// check to ensure the future hasn't been completed with an exception
if (future.isCompletedExceptionally()) {
// call get to force the exception to be thrown for other concurrent callers
future.get();
throw new IllegalStateException("the future was completed exceptionally but no exception was thrown");
}
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
return value;
}
use of java.util.concurrent.CompletableFuture in project vert.x by eclipse.
the class NamedWorkerPoolTest method testDestroyWorkerPoolWhenVerticleUndeploys.
@Test
public void testDestroyWorkerPoolWhenVerticleUndeploys() throws Exception {
String poolName = "vert.x-" + TestUtils.randomAlphaString(10);
AtomicReference<Thread> thread = new AtomicReference<>();
CompletableFuture<String> deploymentIdRef = new CompletableFuture<>();
vertx.deployVerticle(new AbstractVerticle() {
@Override
public void start() throws Exception {
WorkerExecutor pool = vertx.createSharedWorkerExecutor(poolName);
pool.executeBlocking(fut -> {
thread.set(Thread.currentThread());
}, ar -> {
});
}
}, onSuccess(deploymentIdRef::complete));
waitUntil(() -> thread.get() != null);
String deploymentId = deploymentIdRef.get(20, TimeUnit.SECONDS);
vertx.undeploy(deploymentId, onSuccess(v -> {
}));
waitUntil(() -> thread.get().getState() == Thread.State.TERMINATED);
}
Aggregations