use of org.lanternpowered.server.util.ShutdownMonitorThread in project LanternServer by LanternPowered.
the class LanternServer method shutdown.
@SuppressWarnings("deprecation")
@Override
public void shutdown(Text kickMessage) {
checkNotNull(kickMessage, "kickMessage");
if (this.shuttingDown) {
return;
}
this.shuttingDown = true;
// Stop the console
this.consoleManager.shutdown();
final Cause gameCause = Cause.of(EventContext.empty(), this.game);
this.game.postGameStateChange(SpongeEventFactory.createGameStoppingServerEvent(gameCause));
// Debug a message
this.logger.info("Stopping the server... ({})", LanternTexts.toLegacy(kickMessage));
// Kick all the online players
getOnlinePlayers().forEach(player -> ((LanternPlayer) player).getConnection().disconnect(kickMessage));
// Stop the network servers - starts the shutdown process
// It may take a second or two for Netty to totally clean up
this.networkManager.shutdown();
if (this.queryServer != null) {
this.queryServer.shutdown();
}
if (this.rconServer != null) {
this.rconServer.shutdown();
}
// Stop the world manager
this.worldManager.shutdown();
// Shutdown the executor
this.executor.shutdown();
// Stop the async scheduler
this.game.getScheduler().shutdownAsyncScheduler(10, TimeUnit.SECONDS);
final Collection<ProviderRegistration<?>> serviceRegistrations;
try {
final ServiceManager serviceManager = this.game.getServiceManager();
checkState(serviceManager instanceof SimpleServiceManager || serviceManager instanceof LanternServiceManager);
final Field field = (serviceManager instanceof SimpleServiceManager ? SimpleServiceManager.class : LanternServiceManager.class).getDeclaredField("providers");
field.setAccessible(true);
// noinspection unchecked
final Map<Class<?>, ProviderRegistration<?>> map = (Map<Class<?>, ProviderRegistration<?>>) field.get(serviceManager);
serviceRegistrations = map.values();
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
// Close all the services if possible
serviceRegistrations.forEach(provider -> {
final Object service = provider.getProvider();
if (service instanceof CloseableService) {
try {
((CloseableService) service).close();
} catch (Exception e) {
this.logger.error("A error occurred while closing the {}.", provider.getService().getName(), e);
}
}
});
// Shutdown the game profile manager
this.game.getGameProfileManager().getDefaultCache().save();
final GameProfileCache cache = this.game.getGameProfileManager().getCache();
if (cache instanceof CloseableService) {
try {
((CloseableService) cache).close();
} catch (Exception e) {
this.logger.error("A error occurred while closing the GameProfileCache.", e);
}
}
try {
this.game.getOpsConfig().save();
} catch (IOException e) {
this.logger.error("A error occurred while saving the ops config.", e);
}
this.game.postGameStateChange(SpongeEventFactory.createGameStoppedServerEvent(gameCause));
this.game.postGameStateChange(SpongeEventFactory.createGameStoppingEvent(gameCause));
this.game.postGameStateChange(SpongeEventFactory.createGameStoppedEvent(gameCause));
// Wait for a while and terminate any rogue threads
new ShutdownMonitorThread().start();
}
Aggregations