package com.leansoft.luxun.server;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.leansoft.luxun.log.LogManager;
import com.leansoft.luxun.mx.ServerInfo;
import com.leansoft.luxun.mx.ThriftServerStats;
import com.leansoft.luxun.utils.Mx4jLoader;
import com.leansoft.luxun.utils.Scheduler;
import com.leansoft.luxun.utils.Utils;
/**
* The main luxun server container
*
* @author bulldog
*
*/
public class LuxunServer implements Closeable {
final String CLEAN_SHUTDOWN_FILE = ".luxun_cleanshutdown";
final private Logger logger = LoggerFactory.getLogger(LuxunServer.class);
public final ServerConfig config;
final Scheduler scheduler = new Scheduler(1, "luxun-logcleaner", false);
private LogManager logManager;
private final CountDownLatch shutdownLatch = new CountDownLatch(1);
final AtomicBoolean isShuttingDown = new AtomicBoolean(false);
ThriftServer thriftServer;
private final ThriftServerStats stats;
private final File logDir;
private final ServerInfo serverInfo = new ServerInfo();
public LuxunServer(ServerConfig config) {
this.config = config;
logDir = new File(config.getLogDir());
if (!logDir.exists()) {
logDir.mkdirs();
}
this.stats = new ThriftServerStats(1000L * 1000L * 1000L * config.getMonitoringPeriodSecs());
Utils.registerMBean(this.stats);
}
public void startup() {
try {
logger.info("Starting luxun server " + serverInfo.getVersion());
Utils.registerMBean(serverInfo);
boolean needRecovery = true;
File cleanShutDownFile = new File(new File(config.getLogDir()), CLEAN_SHUTDOWN_FILE);
if (cleanShutDownFile.exists()) {
needRecovery = false;
cleanShutDownFile.delete();
}
this.logManager = new LogManager(config,//
scheduler,//
1000L * 60 * config.getLogCleanupIntervalMinutes(),//
1000L * 60 * 60 * config.getLogRetentionHours(),//
needRecovery, this.stats);
logManager.load();
thriftServer = new ThriftServer(this.logManager, this.config, this.stats);
thriftServer.startup();
Mx4jLoader.maybeLoad();
logManager.startup();
serverInfo.started();
logger.info("Server started.");
} catch (Exception ex) {
logger.error("Fatal error during startup.", ex);
try {
close();
} catch (IOException e) {
logger.error("exception during server closing.", e);
}
}
}
@Override
public void close() throws IOException {
boolean canShutdown = isShuttingDown.compareAndSet(false, true);
if (canShutdown) {
logger.info("Shutting down luxun server...");
try {
scheduler.shutdown();
if (this.thriftServer != null) {
this.thriftServer.close();
Utils.unregisterMBean(this.stats);
}
if (this.logManager != null) {
this.logManager.close();
}
File cleanShutDownFile = new File(new File(config.getLogDir()), CLEAN_SHUTDOWN_FILE);
cleanShutDownFile.createNewFile();
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
}
shutdownLatch.countDown();
logger.info("shutdown luxun server completed");
}
}
public void awaitShutdown() throws InterruptedException {
this.shutdownLatch.await();
}
public LogManager getLogManager() {
return this.logManager;
}
public ThriftServerStats getStats() {
return this.thriftServer.getStats();
}
}