use of io.vertx.core.AsyncResult in project vert.x by eclipse.
the class VertxImpl method close.
@Override
public synchronized void close(Handler<AsyncResult<Void>> completionHandler) {
if (closed || eventBus == null) {
// Just call the handler directly since pools shutdown
if (completionHandler != null) {
completionHandler.handle(Future.succeededFuture());
}
return;
}
closed = true;
closeHooks.run(ar -> {
deploymentManager.undeployAll(ar1 -> {
if (haManager() != null) {
haManager().stop();
}
addressResolver.close(ar2 -> {
eventBus.close(ar3 -> {
closeClusterManager(ar4 -> {
Set<HttpServer> httpServers = new HashSet<>(sharedHttpServers.values());
Set<NetServerBase> netServers = new HashSet<>(sharedNetServers.values());
sharedHttpServers.clear();
sharedNetServers.clear();
int serverCount = httpServers.size() + netServers.size();
AtomicInteger serverCloseCount = new AtomicInteger();
Handler<AsyncResult<Void>> serverCloseHandler = res -> {
if (res.failed()) {
log.error("Failure in shutting down server", res.cause());
}
if (serverCloseCount.incrementAndGet() == serverCount) {
deleteCacheDirAndShutdown(completionHandler);
}
};
for (HttpServer server : httpServers) {
server.close(serverCloseHandler);
}
for (NetServerBase server : netServers) {
server.close(serverCloseHandler);
}
if (serverCount == 0) {
deleteCacheDirAndShutdown(completionHandler);
}
});
});
});
});
});
}
use of io.vertx.core.AsyncResult in project vert.x by eclipse.
the class NetServerBase method listen.
public synchronized void listen(Handler<? super C> handler, int port, String host, Handler<AsyncResult<Void>> listenHandler) {
if (handler == null) {
throw new IllegalStateException("Set connect handler first");
}
if (listening) {
throw new IllegalStateException("Listen already called");
}
listening = true;
listenContext = vertx.getOrCreateContext();
registeredHandler = handler;
synchronized (vertx.sharedNetServers()) {
// Will be updated on bind for a wildcard port
this.actualPort = port;
id = new ServerID(port, host);
NetServerBase shared = vertx.sharedNetServers().get(id);
if (shared == null || port == 0) {
// Wildcard port will imply a new actual server each time
serverChannelGroup = new DefaultChannelGroup("vertx-acceptor-channels", GlobalEventExecutor.INSTANCE);
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(availableWorkers);
bootstrap.channel(NioServerSocketChannel.class);
sslHelper.validate(vertx);
bootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
if (isPaused()) {
ch.close();
return;
}
ChannelPipeline pipeline = ch.pipeline();
NetServerBase.this.initChannel(ch.pipeline());
pipeline.addLast("handler", new ServerHandler(ch));
}
});
applyConnectionOptions(bootstrap);
handlerManager.addHandler(handler, listenContext);
try {
bindFuture = AsyncResolveConnectHelper.doBind(vertx, port, host, bootstrap);
bindFuture.addListener(res -> {
if (res.succeeded()) {
Channel ch = res.result();
log.trace("Net server listening on " + host + ":" + ch.localAddress());
NetServerBase.this.actualPort = ((InetSocketAddress) ch.localAddress()).getPort();
NetServerBase.this.id = new ServerID(NetServerBase.this.actualPort, id.host);
serverChannelGroup.add(ch);
vertx.sharedNetServers().put(id, NetServerBase.this);
metrics = vertx.metricsSPI().createMetrics(new SocketAddressImpl(id.port, id.host), options);
} else {
vertx.sharedNetServers().remove(id);
}
});
} catch (Throwable t) {
// Make sure we send the exception back through the handler (if any)
if (listenHandler != null) {
vertx.runOnContext(v -> listenHandler.handle(Future.failedFuture(t)));
} else {
// No handler - log so user can see failure
log.error(t);
}
listening = false;
return;
}
if (port != 0) {
vertx.sharedNetServers().put(id, this);
}
actualServer = this;
} else {
// Server already exists with that host/port - we will use that
actualServer = shared;
this.actualPort = shared.actualPort();
metrics = vertx.metricsSPI().createMetrics(new SocketAddressImpl(id.port, id.host), options);
actualServer.handlerManager.addHandler(handler, listenContext);
}
// just add it to the future so it gets notified once the bind is complete
actualServer.bindFuture.addListener(res -> {
if (listenHandler != null) {
AsyncResult<Void> ares;
if (res.succeeded()) {
ares = Future.succeededFuture();
} else {
listening = false;
ares = Future.failedFuture(res.cause());
}
listenContext.runOnContext(v -> listenHandler.handle(ares));
} else if (res.failed()) {
log.error("Failed to listen", res.cause());
listening = false;
}
});
}
return;
}
use of io.vertx.core.AsyncResult in project vert.x by eclipse.
the class Http2ServerConnection method sendPush.
synchronized void sendPush(int streamId, String host, HttpMethod method, MultiMap headers, String path, Handler<AsyncResult<HttpServerResponse>> completionHandler) {
Http2Headers headers_ = new DefaultHttp2Headers();
if (method == HttpMethod.OTHER) {
throw new IllegalArgumentException("Cannot push HttpMethod.OTHER");
} else {
headers_.method(method.name());
}
headers_.path(path);
headers_.scheme(isSsl() ? "https" : "http");
if (host != null) {
headers_.authority(host);
}
if (headers != null) {
headers.forEach(header -> headers_.add(header.getKey(), header.getValue()));
}
handler.writePushPromise(streamId, headers_, new Handler<AsyncResult<Integer>>() {
@Override
public void handle(AsyncResult<Integer> ar) {
if (ar.succeeded()) {
synchronized (Http2ServerConnection.this) {
int promisedStreamId = ar.result();
String contentEncoding = HttpUtils.determineContentEncoding(headers_);
Http2Stream promisedStream = handler.connection().stream(promisedStreamId);
boolean writable = handler.encoder().flowController().isWritable(promisedStream);
Push push = new Push(promisedStream, contentEncoding, method, path, writable, completionHandler);
streams.put(promisedStreamId, push);
if (maxConcurrentStreams == null || concurrentStreams < maxConcurrentStreams) {
concurrentStreams++;
context.executeFromIO(push::complete);
} else {
pendingPushes.add(push);
}
}
} else {
context.executeFromIO(() -> {
completionHandler.handle(Future.failedFuture(ar.cause()));
});
}
}
});
}
use of io.vertx.core.AsyncResult in project vert.x by eclipse.
the class DnsClientImpl method reverseLookup.
@Override
public DnsClient reverseLookup(String address, Handler<AsyncResult<String>> handler) {
// An other option would be to change address to be of type InetAddress.
try {
InetAddress inetAddress = InetAddress.getByName(address);
byte[] addr = inetAddress.getAddress();
StringBuilder reverseName = new StringBuilder(64);
if (inetAddress instanceof Inet4Address) {
// reverse ipv4 address
reverseName.append(addr[3] & 0xff).append(".").append(addr[2] & 0xff).append(".").append(addr[1] & 0xff).append(".").append(addr[0] & 0xff);
} else {
// It is an ipv 6 address time to reverse it
for (int i = 0; i < 16; i++) {
reverseName.append(HEX_TABLE[(addr[15 - i] & 0xf)]);
reverseName.append(".");
reverseName.append(HEX_TABLE[(addr[15 - i] >> 4) & 0xf]);
if (i != 15) {
reverseName.append(".");
}
}
}
reverseName.append(".in-addr.arpa");
return resolvePTR(reverseName.toString(), handler);
} catch (UnknownHostException e) {
// Should never happen as we work with ip addresses as input
// anyway just in case notify the handler
actualCtx.runOnContext((v) -> handler.handle(Future.failedFuture(e)));
}
return this;
}
use of io.vertx.core.AsyncResult in project vert.x by eclipse.
the class HttpServerResponseImpl method doSendFile.
private void doSendFile(String filename, long offset, long length, Handler<AsyncResult<Void>> resultHandler) {
synchronized (conn) {
if (headWritten) {
throw new IllegalStateException("Head already written");
}
checkWritten();
File file = vertx.resolveFile(filename);
if (!file.exists()) {
if (resultHandler != null) {
ContextImpl ctx = vertx.getOrCreateContext();
ctx.runOnContext((v) -> resultHandler.handle(Future.failedFuture(new FileNotFoundException())));
} else {
log.error("File not found: " + filename);
}
return;
}
long contentLength = Math.min(length, file.length() - offset);
bytesWritten = contentLength;
if (!contentLengthSet()) {
putHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
}
if (!contentTypeSet()) {
String contentType = MimeMapping.getMimeTypeForFilename(filename);
if (contentType != null) {
putHeader(HttpHeaders.CONTENT_TYPE, contentType);
}
}
prepareHeaders();
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "r");
conn.queueForWrite(response);
conn.sendFile(raf, Math.min(offset, file.length()), contentLength);
} catch (IOException e) {
try {
if (raf != null) {
raf.close();
}
} catch (IOException ignore) {
}
if (resultHandler != null) {
ContextImpl ctx = vertx.getOrCreateContext();
ctx.runOnContext((v) -> resultHandler.handle(Future.failedFuture(e)));
} else {
log.error("Failed to send file", e);
}
return;
}
// write an empty last content to let the http encoder know the response is complete
channelFuture = conn.writeToChannel(LastHttpContent.EMPTY_LAST_CONTENT);
written = true;
if (resultHandler != null) {
ContextImpl ctx = vertx.getOrCreateContext();
channelFuture.addListener(future -> {
AsyncResult<Void> res;
if (future.isSuccess()) {
res = Future.succeededFuture();
} else {
res = Future.failedFuture(future.cause());
}
ctx.runOnContext((v) -> resultHandler.handle(res));
});
}
if (!keepAlive) {
closeConnAfterWrite();
}
conn.responseComplete();
if (bodyEndHandler != null) {
bodyEndHandler.handle(null);
}
}
}
Aggregations