public void handleSessionEvent(GearmanSessionEvent event)
     throws IllegalArgumentException, IllegalStateException {
   GearmanPacket p = event.getPacket();
   GearmanJobServerSession s = event.getSession();
   GearmanPacketType t = p.getPacketType();
   LOG.debug(
       "Worker "
           + this
           + " handling session event"
           + " ( Session = "
           + s
           + " Event = "
           + t
           + " )");
   switch (t) {
     case JOB_ASSIGN:
       // TODO Figure out what the right behavior is if JobUUIDRequired was false when we submitted
       // but is now true
       taskMap.remove(s);
       addNewJob(event);
       break;
     case JOB_ASSIGN_UNIQ:
       // TODO Figure out what the right behavior is if JobUUIDRequired was true when we submitted
       // but is now false
       taskMap.remove(s);
       addNewJob(event);
       break;
     case NOOP:
       taskMap.remove(s);
       break;
     case NO_JOB:
       GearmanTask preSleepTask =
           new GearmanTask(
               new GrabJobEventHandler(s),
               new GearmanPacketImpl(
                   GearmanPacketMagic.REQ, GearmanPacketType.PRE_SLEEP, new byte[0]));
       taskMap.put(s, preSleepTask);
       s.submitTask(preSleepTask);
       break;
     case ECHO_RES:
       break;
     case OPTION_RES:
       break;
     case ERROR:
       s.closeSession();
       break;
     default:
       LOG.warn(
           "Received unknown packet type " + t + " from session " + s + ". Closing connection.");
       s.closeSession();
   }
 }
 public List<Runnable> shutdownNow() {
   runState = state.SHUTTINGDOWN;
   LOG.info("Commencing immediate shutdown of client: " + this);
   timer.cancel();
   Iterator<GearmanJobServerSession> sessions = sessionsMap.values().iterator();
   while (sessions.hasNext()) {
     GearmanJobServerSession curSession = sessions.next();
     if (!curSession.isInitialized()) {
       continue;
     }
     try {
       curSession.closeSession();
     } catch (Exception e) {
       LOG.warn(
           "Failed to closes session "
               + curSession
               + " while performing immediate shutdown of client "
               + this
               + ". Encountered the following exception "
               + e);
     }
     sessions.remove();
   }
   sessionsMap.clear();
   sessionsMap = null;
   runState = state.TERMINATED;
   try {
     ioAvailable.close();
   } catch (IOException ioe) {
     LOG.warn("Encountered IOException while closing selector for client ", ioe);
   }
   LOG.info("Completed shutdown of client: " + this);
   return new ArrayList<Runnable>();
 }
  /*
   * For the time being this will always return an empty list of
   * exceptions because closeSession does not throw an exception
   */
  private List<Exception> shutDownWorker(boolean completeTasks) {
    LOG.info("Commencing shutdowm of worker " + this);

    ArrayList<Exception> exceptions = new ArrayList<Exception>();

    // This gives any jobs in flight a chance to complete
    if (executorService != null) {
      if (completeTasks) {
        executorService.shutdown();
      } else {
        executorService.shutdownNow();
      }
    }

    for (GearmanJobServerSession sess : sessionMap.values()) {
      sess.closeSession();
    }
    try {
      ioAvailable.close();
    } catch (IOException ioe) {
      LOG.warn("Encountered IOException while closing selector for worker: ", ioe);
    }
    state = State.IDLE;
    LOG.info("Completed shutdowm of worker " + this);

    return exceptions;
  }
 private void shutDownSession(GearmanJobServerSession s) {
   if (s.isInitialized()) {
     SelectionKey k = s.getSelectionKey();
     if (k != null) {
       sessionsMap.remove(k);
       k.cancel();
     }
     s.closeSession();
   }
   sessionJobsMap.remove(s);
 }
  public void work() {
    if (!state.equals(State.IDLE)) {
      throw new IllegalStateException(
          "Can not call work while worker " + "is running or shutting down");
    }

    state = State.RUNNING;
    // a map keeping track of sessions with connection errors
    // (to avoid printing an error about them in every reconnect attempt)
    Map<GearmanJobServerSession, Boolean> havingConnectionError =
        new HashMap<GearmanJobServerSession, Boolean>();

    while (isRunning()) {

      // look for sessions which have been disconnected and attempt to reconnect.
      for (Iterator<GearmanJobServerSession> iter = sessionMap.values().iterator();
          iter.hasNext(); ) {
        GearmanJobServerSession sess = iter.next();
        if (!sess.isInitialized()) {
          try {

            // reconnect, unregister old selection key and register new one
            SelectionKey oldKey = sess.isInitialized() ? sess.getSelectionKey() : null;
            sess.initSession(ioAvailable, this);
            if (oldKey != null) {
              iter.remove();
            }
            sessionMap.put(sess.getSelectionKey(), sess);

            // register all functions with the newly reconnected server
            for (FunctionDefinition d : functionMap.values()) {
              GearmanTask gsr = new GearmanTask(null, generateCanDoPacket(d));
              sess.submitTask(gsr);
            }

            GearmanPacket p =
                new GearmanPacketImpl(
                    GearmanPacketMagic.REQ,
                    GearmanPacketType.SET_CLIENT_ID,
                    ByteUtils.toUTF8Bytes(id));
            sess.submitTask(new GearmanTask(p));

            GearmanTask sessTask =
                new GearmanTask(
                    new GrabJobEventHandler(sess),
                    new GearmanPacketImpl(
                        GearmanPacketMagic.REQ, getGrabJobPacketType(), new byte[0]));
            sess.submitTask(sessTask);
            sess.driveSessionIO();

            // log reconnection message
            if (havingConnectionError.get(sess)) {
              LOG.info("Re-established connection to " + sess.getConnection().toString());
            }
            havingConnectionError.put(sess, false);
          } catch (IOException e) {
            if (!havingConnectionError.get(sess)) {
              LOG.warn("Error connecting to " + sess + ", will keep trying..");
            }

            havingConnectionError.put(sess, true);

            try {
              Thread.sleep(50);
            } catch (InterruptedException e1) {
            }
          }
        } else {
          havingConnectionError.put(sess, false);
        }
      }

      for (GearmanJobServerSession sess : sessionMap.values()) {
        // if still disconnected, skip
        if (!sess.isInitialized()) {
          continue;
        }
        int interestOps = SelectionKey.OP_READ;
        if (sess.sessionHasDataToWrite()) {
          interestOps |= SelectionKey.OP_WRITE;
        }
        sess.getSelectionKey().interestOps(interestOps);
      }
      try {
        ioAvailable.select(1);
      } catch (IOException io) {
        LOG.warn("Receieved IOException while" + " selecting for IO", io);
      }

      for (SelectionKey key : ioAvailable.selectedKeys()) {
        GearmanJobServerSession sess = sessionMap.get(key);
        if (sess == null) {
          LOG.warn("Worker does not have " + "session for key " + key);
          continue;
        }
        if (!sess.isInitialized()) {
          continue;
        }
        try {
          GearmanTask sessTask = taskMap.get(sess);
          if (sessTask == null) {
            sessTask =
                new GearmanTask( // NOPMD
                    new GrabJobEventHandler(sess),
                    new GearmanPacketImpl(
                        GearmanPacketMagic.REQ, getGrabJobPacketType(), new byte[0]));
            taskMap.put(sess, sessTask);
            sess.submitTask(sessTask);
            LOG.debug(
                "Worker: "
                    + this
                    + " submitted a "
                    + sessTask.getRequestPacket().getPacketType()
                    + " to session: "
                    + sess);
          }
          sess.driveSessionIO();
          // For the time being we will execute the jobs synchronously
          // in the future, I expect to change this.
          if (!functionList.isEmpty()) {
            GearmanFunction fun = functionList.remove();
            submitFunction(fun);
            statistics();
          }

        } catch (IOException ioe) {
          LOG.warn("Received IOException while driving" + " IO on session " + sess, ioe);
          sess.closeSession();
          continue;
        }
      }
    }

    shutDownWorker(true);
  }