/**
  * Unlike a Follower, which sees a full request only during the PROPOSAL phase, Observers get all
  * the data required with the INFORM packet. This method commits a request that has been unpacked
  * by from an INFORM received from the Leader.
  *
  * @param request
  */
 public void commitRequest(Request request) {
   if (syncRequestProcessorEnabled) {
     // Write to txnlog and take periodic snapshot
     syncProcessor.processRequest(request);
   }
   commitProcessor.commit(request);
 }
  /**
   * Set up the request processors for an Observer: firstProcesor->commitProcessor->finalProcessor
   */
  @Override
  protected void setupRequestProcessors() {
    // We might consider changing the processor behaviour of
    // Observers to, for example, remove the disk sync requirements.
    // Currently, they behave almost exactly the same as followers.
    RequestProcessor finalProcessor = new FinalRequestProcessor(this);
    commitProcessor =
        new CommitProcessor(
            finalProcessor, Long.toString(getServerId()), true, getZooKeeperServerListener());
    commitProcessor.start();
    firstProcessor = new ObserverRequestProcessor(this, commitProcessor);
    ((ObserverRequestProcessor) firstProcessor).start();

    /*
     * Observer should write to disk, so that the it won't request
     * too old txn from the leader which may lead to getting an entire
     * snapshot.
     *
     * However, this may degrade performance as it has to write to disk
     * and do periodic snapshot which may double the memory requirements
     */
    if (syncRequestProcessorEnabled) {
      syncProcessor = new SyncRequestProcessor(this, null);
      syncProcessor.start();
    }
  }
 @Override
 public synchronized void shutdown() {
   if (!canShutdown()) {
     LOG.debug("ZooKeeper server is not running, so not proceeding to shutdown!");
     return;
   }
   super.shutdown();
   if (syncRequestProcessorEnabled && syncProcessor != null) {
     syncProcessor.shutdown();
   }
 }