package jj;
import static java.util.concurrent.TimeUnit.*;
import static jj.server.ServerLocation.Root;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import javax.inject.Singleton;
import jj.event.Publisher;
import jj.execution.JJTask;
import jj.execution.ServerTask;
import jj.execution.TaskRunner;
import jj.server.Server;
@Singleton
public class JJServerLifecycle {
private final Server server;
private final Publisher publisher;
private final TaskRunner taskRunner;
private final Version version;
private final AtomicBoolean started = new AtomicBoolean(false);
@Inject
JJServerLifecycle(
final Server server,
final Publisher publisher,
final TaskRunner taskRunner,
final Version version
) {
this.server = server;
this.publisher = publisher;
this.taskRunner = taskRunner;
this.version = version;
}
public void start() throws Exception {
if (started.compareAndSet(false, true)) {
ServerStarting startupEvent = new ServerStarting(server.resolvePath(Root), version);
publisher.publish(startupEvent);
for (ServerStarting.Priority priority : ServerStarting.Priority.values()) {
List<JJTask<?>> tasks = startupEvent.startupTasks().get(priority);
if (tasks != null) {
CountDownLatch latch = new CountDownLatch(tasks.size());
for (JJTask<?> task : tasks) {
taskRunner.execute(task).then(new ServerTask("counting down " + priority + " priority startup tasks") {
@Override
protected void run() throws Exception {
latch.countDown();
}
});
}
latch.await(1, SECONDS);
}
}
} else {
// getting double started is bad!
new Error("being double started!").printStackTrace();
//System.exit(1);
}
}
public void stop() {
if (started.compareAndSet(true, false)) {
publisher.publish(new ServerStopping());
} else {
// getting double stooped is also bad!
new Error("being double stopped!").printStackTrace();
//System.exit(1);
}
}
}