com.github.raduciumag.shapeshift.server.BaseServer Maven / Gradle / Ivy
package com.github.raduciumag.shapeshift.server;
import com.github.raduciumag.shapeshift.config.ServerConfig;
import com.github.raduciumag.shapeshift.model.server.ServerStatus;
import com.google.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.locks.ReentrantLock;
public abstract class BaseServer implements Server {
private static final Logger LOG = LoggerFactory.getLogger(BaseServer.class);
protected final T config;
protected final Thread startThread;
protected final Thread stopThread;
protected ServerStatus status = ServerStatus.STOPPED;
protected ReentrantLock statusLock = new ReentrantLock();
public BaseServer(final T config) {
this.config = config;
this.startThread = new Thread(this::startInternal);
this.stopThread = new Thread(() -> {
try {
stopInternal();
} catch (final InterruptedException exc) {
LOG.error("Server stop interrupted", exc);
}
});
}
@Override
public void start() {
Preconditions.checkArgument(config != null, "The server configuration is required");
statusLock.lock();
try {
Preconditions.checkState(status == ServerStatus.STOPPED, "The server status " + status + " does not allow " +
"a start command");
Preconditions.checkState(!startThread.isAlive(), "The server is already started");
LOG.info("Starting \"{}\" server", config.getName());
startThread.start();
} finally {
statusLock.unlock();
}
}
protected abstract void startInternal();
@Override
public void stop() {
Preconditions.checkArgument(config != null, "The server configuration is required");
statusLock.lock();
try {
Preconditions.checkState(status == ServerStatus.STARTED, "The server status " + status + " does not allow " +
"a stop command");
Preconditions.checkState(!stopThread.isAlive(), "The server is already stopping");
LOG.info("Stopping \"{}\" server", config.getName());
stopThread.start();
} finally {
statusLock.unlock();
}
}
protected abstract void stopInternal() throws InterruptedException;
@Override
public T getConfig() {
return config;
}
@Override
public ServerStatus getStatus() {
return status;
}
}