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); }