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>(); }
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException { TimeUnit sessionUnit = TimeUnit.MILLISECONDS; long timeLeft = -1; long timeOutInMills = timeout < 0 ? -1 : TimeUnit.MILLISECONDS.convert(timeout, unit) + System.currentTimeMillis(); if (getNumberofActiveJobs() == 0) { return true; } for (GearmanJobServerSession curSession : sessionsMap.values()) { if (!(curSession.isInitialized())) { continue; } // negative timeout means block till completion if (timeout >= 0) { timeLeft = timeOutInMills - System.currentTimeMillis(); if (timeLeft <= 0) { LOG.warn("awaitTermination exceeded timeout."); break; } } try { curSession.waitForTasksToComplete(timeLeft, sessionUnit); } catch (TimeoutException te) { LOG.info("timed out waiting for all tasks to complete"); break; } } return getNumberofActiveJobs() == 0; }
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); }
private GearmanJobServerSession getSessionForTask() throws IOException { if (sessionsMap.values().isEmpty()) { throw new IOException("No servers registered with client"); } ArrayList<GearmanJobServerSession> sessions = new ArrayList<GearmanJobServerSession>(); sessions.addAll(sessionsMap.values()); Random rand = new Random(System.currentTimeMillis()); int s = rand.nextInt(sessions.size()); GearmanJobServerSession session = sessions.get(s); IOException ioe = new IOException("No servers available for client"); for (int i = 0; i < sessions.size(); i++) { if (!session.isInitialized()) { try { session.initSession(ioAvailable, this); sessionsMap.put(session.getSelectionKey(), session); } catch (Exception e) { if (sessions.size() > 1) { // try next one int prev = s; s = (s + 1) % sessions.size(); session = sessions.get(s); LOG.warn( "Got exception attempting to retrieve " + "session for task. Try next server at " + "pos={}, previous pos={}", s, prev); continue; } else { break; } } } return session; } throw ioe; }
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); }