Close the clients when the JVM is shutting down

This commit is contained in:
Andrea Cavalli 2021-10-06 20:39:53 +02:00
parent d273db0df9
commit c39f101002
2 changed files with 37 additions and 0 deletions

View File

@ -23,8 +23,11 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
private static final Marker TG_MARKER = MarkerFactory.getMarker("TG"); private static final Marker TG_MARKER = MarkerFactory.getMarker("TG");
private static final Logger logger = LoggerFactory.getLogger(TelegramClient.class); private static final Logger logger = LoggerFactory.getLogger(TelegramClient.class);
private final ConcurrentHashMap<Long, Handler> handlers = new ConcurrentHashMap<Long, Handler>(); private final ConcurrentHashMap<Long, Handler> handlers = new ConcurrentHashMap<Long, Handler>();
private final Thread shutdownHook = new Thread(this::onJVMShutdown);
private volatile Integer clientId = null; private volatile Integer clientId = null;
private final InternalClientManager clientManager; private final InternalClientManager clientManager;
private Handler updateHandler; private Handler updateHandler;
@ -35,6 +38,7 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
public InternalClient(InternalClientManager clientManager) { public InternalClient(InternalClientManager clientManager) {
this.clientManager = clientManager; this.clientManager = clientManager;
Runtime.getRuntime().addShutdownHook(shutdownHook);
} }
@Override @Override
@ -81,6 +85,11 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
private void handleClose() { private void handleClose() {
logger.trace(TG_MARKER, "Received close"); logger.trace(TG_MARKER, "Received close");
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ignored) {
logger.trace(TG_MARKER, "Can't remove shutdown hook because the JVM is already shutting down");
}
handlers.forEach((eventId, handler) -> { handlers.forEach((eventId, handler) -> {
handleResponse(eventId, new Error(500, "Instance closed"), handler); handleResponse(eventId, new Error(500, "Instance closed"), handler);
}); });
@ -181,6 +190,15 @@ public final class InternalClient implements ClientEventsHandler, TelegramClient
return NativeClientAccess.execute(query); return NativeClientAccess.execute(query);
} }
private void onJVMShutdown() {
try {
logger.info(TG_MARKER, "Client {} is shutting down because the JVM is shutting down", clientId);
this.send(new TdApi.Close(), result -> {}, ex -> {});
} catch (Throwable ex) {
logger.debug("Failed to send shutdown request to session {}", clientId);
}
}
/** /**
* *
* @param function function used to check if the check will be enforced or not. Can be null * @param function function used to check if the check will be enforced or not. Can be null

View File

@ -38,6 +38,8 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
private final ExceptionHandler defaultExceptionHandler; private final ExceptionHandler defaultExceptionHandler;
private final Handler updateHandler; private final Handler updateHandler;
private final Thread shutdownHook = new Thread(this::onJVMShutdown);
private volatile Integer clientId = null; private volatile Integer clientId = null;
private final InternalClientManager clientManager; private final InternalClientManager clientManager;
@ -48,6 +50,7 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
this.clientManager = clientManager; this.clientManager = clientManager;
this.updateHandler = new Handler(this::onUpdateFromHandler, this::onUpdateException); this.updateHandler = new Handler(this::onUpdateFromHandler, this::onUpdateException);
this.defaultExceptionHandler = this::onDefaultException; this.defaultExceptionHandler = this::onDefaultException;
Runtime.getRuntime().addShutdownHook(shutdownHook);
} }
@Override @Override
@ -72,6 +75,12 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
* This method will be called exactly once * This method will be called exactly once
*/ */
private void handleClose() { private void handleClose() {
logger.trace(TG_MARKER, "Received close");
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ignored) {
logger.trace(TG_MARKER, "Can't remove shutdown hook because the JVM is already shutting down");
}
TdApi.Error instanceClosedError = new Error(500, "Instance closed"); TdApi.Error instanceClosedError = new Error(500, "Instance closed");
handlers.forEach((eventId, handler) -> this.handleResponse(eventId, instanceClosedError, handler)); handlers.forEach((eventId, handler) -> this.handleResponse(eventId, instanceClosedError, handler));
handlers.clear(); handlers.clear();
@ -90,6 +99,7 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
if (signalListener != null) { if (signalListener != null) {
signalListener.onSignal(Signal.ofClosed()); signalListener.onSignal(Signal.ofClosed());
} }
logger.info(TG_MARKER, "Client closed {}", clientId);
} }
/** /**
@ -299,6 +309,15 @@ public final class InternalReactiveClient implements ClientEventsHandler, Reacti
} }
} }
private void onJVMShutdown() {
try {
logger.info(TG_MARKER, "Client {} is shutting down because the JVM is shutting down", clientId);
sendCloseAndIgnoreResponse();
} catch (Throwable ex) {
logger.debug("Failed to send shutdown request to session {}", clientId);
}
}
/** /**
* @param function function used to check if the check will be enforced or not. Can be null * @param function function used to check if the check will be enforced or not. Can be null
* @return true if closed * @return true if closed