Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * This code is placed in the public domain by its author, Tim Peierls.
- */
- package com.example.server;
- import com.google.common.base.Throwables;
- import com.google.common.util.concurrent.AbstractIdleService;
- import com.google.common.util.concurrent.Service;
- import java.util.concurrent.atomic.AtomicBoolean;
- import javax.inject.Inject;
- import javax.inject.Singleton;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- * Service that manages a {@link MainComponent} and possibly other
- * sub-services with lifecycles, handling start/stop requests in dedicated thread.
- */
- @Singleton
- public class MainService extends AbstractIdleService implements Service {
- final static Logger logger = LoggerFactory.getLogger(MainService.class);
- /**
- * Saves references to the objects being managed.
- */
- @Inject MainService(MainComponent component,
- // Other dependencies here, e.g., sub-services.
- DeploymentMode deploymentMode) {
- this.exitAfterStopping = new AtomicBoolean(false);
- this.stopCalled = new AtomicBoolean(false);
- this.deploymentMode = deploymentMode;
- this.component = component;
- // Save other dependencies here.
- }
- //
- // AbstractIdleService methods - these do the actual start/stop behavior.
- //
- @Override protected void startUp() {
- try {
- // Arrange to exit JVM when service is stopped and
- // to stop service when JVM exits. Only relevant in
- // standalone mode.
- if (deploymentMode == DeploymentMode.STANDALONE) {
- registerForShutdown();
- }
- component.start();
- // Start other sub-services here.
- } catch (Exception ex) {
- throw Throwables.propagate(ex);
- }
- }
- @Override protected void shutDown() {
- try {
- stopInCurrentThread();
- } finally {
- if (exitAfterStopping.get()) {
- System.exit(0);
- }
- }
- }
- /**
- * Starts service and ensures system exit when service
- * stops (and service stop when system exits).
- */
- void registerForShutdown() {
- if (exitAfterStopping.compareAndSet(false, true)) {
- Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
- public void run() {
- try {
- // Call service.stopInCurrentThread() rather than
- // service.stop(), because the latter would involve
- // another thread in a shutdown hook, which is a no-no.
- stopInCurrentThread();
- } catch (Exception ignore) {
- // Can't do anything with exceptions during shutdown.
- logger.warn("Ignoring exception in shutdown: {}", ignore);
- }
- }
- }));
- }
- }
- /**
- * Stops the Restlet component and other services idempotently.
- */
- private void stopInCurrentThread() {
- if (stopCalled.compareAndSet(false, true)) {
- Exception exceptionStoppingComponent = null;
- try {
- component.stop();
- } catch (Exception ex) {
- exceptionStoppingComponent = ex;
- } finally {
- try {
- // Stop a service.
- } finally {
- try {
- // Stop another service.
- } finally {
- if (exceptionStoppingComponent != null) {
- throw Throwables.propagate(exceptionStoppingComponent);
- }
- }
- }
- }
- }
- }
- private final AtomicBoolean exitAfterStopping;
- private final AtomicBoolean stopCalled;
- private final DeploymentMode deploymentMode;
- private final MainComponent component;
- // Fields for other dependencies here.
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement