SHARE
TWEET

com.example.server.MainService

tpeierls Jan 23rd, 2012 194 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * This code is placed in the public domain by its author, Tim Peierls.
  3.  */
  4. package com.example.server;
  5.  
  6. import com.google.common.base.Throwables;
  7. import com.google.common.util.concurrent.AbstractIdleService;
  8. import com.google.common.util.concurrent.Service;
  9.  
  10. import java.util.concurrent.atomic.AtomicBoolean;
  11.  
  12. import javax.inject.Inject;
  13. import javax.inject.Singleton;
  14.  
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17.  
  18.  
  19. /**
  20.  * Service that manages a {@link MainComponent} and possibly other
  21.  * sub-services with lifecycles, handling start/stop requests in dedicated thread.
  22.  */
  23. @Singleton
  24. public class MainService extends AbstractIdleService implements Service {
  25.  
  26.     final static Logger logger = LoggerFactory.getLogger(MainService.class);
  27.  
  28.  
  29.     /**
  30.      * Saves references to the objects being managed.
  31.      */
  32.     @Inject MainService(MainComponent component,
  33.                         // Other dependencies here, e.g., sub-services.
  34.                         DeploymentMode deploymentMode) {
  35.         this.exitAfterStopping  = new AtomicBoolean(false);
  36.         this.stopCalled         = new AtomicBoolean(false);
  37.         this.deploymentMode     = deploymentMode;
  38.         this.component          = component;
  39.         // Save other dependencies here.
  40.     }
  41.  
  42.  
  43.     //
  44.     // AbstractIdleService methods - these do the actual start/stop behavior.
  45.     //
  46.  
  47.     @Override protected void startUp() {
  48.         try {
  49.             // Arrange to exit JVM when service is stopped and
  50.             // to stop service when JVM exits. Only relevant in
  51.             // standalone mode.
  52.             if (deploymentMode == DeploymentMode.STANDALONE) {
  53.                 registerForShutdown();
  54.             }
  55.  
  56.             component.start();
  57.  
  58.             // Start other sub-services here.
  59.         } catch (Exception ex) {
  60.             throw Throwables.propagate(ex);
  61.         }
  62.     }
  63.  
  64.     @Override protected void shutDown() {
  65.         try {
  66.             stopInCurrentThread();
  67.         } finally {
  68.             if (exitAfterStopping.get()) {
  69.                 System.exit(0);
  70.             }
  71.         }
  72.     }
  73.  
  74.  
  75.     /**
  76.      * Starts service and ensures system exit when service
  77.      * stops (and service stop when system exits).
  78.      */
  79.     void registerForShutdown() {
  80.         if (exitAfterStopping.compareAndSet(false, true)) {
  81.             Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
  82.                 public void run() {
  83.                     try {
  84.                         // Call service.stopInCurrentThread() rather than
  85.                         // service.stop(), because the latter would involve
  86.                         // another thread in a shutdown hook, which is a no-no.
  87.                         stopInCurrentThread();
  88.                     } catch (Exception ignore) {
  89.                         // Can't do anything with exceptions during shutdown.
  90.                         logger.warn("Ignoring exception in shutdown: {}", ignore);
  91.                     }
  92.                 }
  93.             }));
  94.         }
  95.     }
  96.  
  97.  
  98.     /**
  99.      * Stops the Restlet component and other services idempotently.
  100.      */
  101.     private void stopInCurrentThread() {
  102.         if (stopCalled.compareAndSet(false, true)) {
  103.             Exception exceptionStoppingComponent = null;
  104.             try {
  105.                 component.stop();
  106.             } catch (Exception ex) {
  107.                 exceptionStoppingComponent = ex;
  108.             } finally {
  109.                 try {
  110.                     // Stop a service.
  111.                 } finally {
  112.                     try {
  113.                         // Stop another service.
  114.                     } finally {
  115.                         if (exceptionStoppingComponent != null) {
  116.                             throw Throwables.propagate(exceptionStoppingComponent);
  117.                         }
  118.                     }
  119.                 }
  120.             }
  121.         }
  122.     }
  123.  
  124.     private final AtomicBoolean exitAfterStopping;
  125.     private final AtomicBoolean stopCalled;
  126.     private final DeploymentMode deploymentMode;
  127.     private final MainComponent component;
  128.     // Fields for other dependencies here.
  129. }
RAW Paste Data
Top