public void removeJobServer(GearmanJobServerConnection conn) throws IllegalArgumentException, IllegalStateException { if (!runState.equals(state.RUNNING)) { throw new IllegalStateException( "JobServers can not be removed " + "once shutdown has been commenced."); } // TODO, make this better Iterator<GearmanJobServerSession> iter = sessionsMap.values().iterator(); GearmanJobServerSession session = null; boolean foundit = false; while (iter.hasNext() && !foundit) { session = iter.next(); if (session.getConnection().equals(conn)) { foundit = true; } } if (!foundit) { throw new IllegalArgumentException( "JobServer " + conn + " has not" + " been registered with this client."); } shutDownSession(session); LOG.info("Removed job server " + conn + " from client " + this); }
public boolean addServer(GearmanJobServerConnection conn) throws IllegalArgumentException, IllegalStateException { if (conn == null) { throw new IllegalArgumentException("Connection can not be null"); } // this is a sub-optimal way to look for dups, but addJobServer // ops should be infrequent enough that this should be a big penalty for (GearmanJobServerSession sess : sessionMap.values()) { if (sess.getConnection().equals(conn)) { return true; } } GearmanJobServerSession session = new GearmanJobServerSession(conn); if (ioAvailable == null) { try { ioAvailable = Selector.open(); } catch (IOException ioe) { LOG.warn("Failed to connect to job server " + conn + ".", ioe); return false; } } try { session.initSession(ioAvailable, this); } catch (IOException ioe) { LOG.warn("Failed to initialize session with job server " + conn + ".", ioe); return false; } SelectionKey key = session.getSelectionKey(); if (key == null) { String msg = "Session " + session + " has a null " + "selection key. Server will not be added to worker."; LOG.warn(msg); throw new IllegalStateException(msg); } sessionMap.put(key, session); GearmanPacket p = new GearmanPacketImpl( GearmanPacketMagic.REQ, GearmanPacketType.SET_CLIENT_ID, ByteUtils.toUTF8Bytes(id)); session.submitTask(new GearmanTask(p)); for (FunctionDefinition def : functionMap.values()) { p = generateCanDoPacket(def); session.submitTask(new GearmanTask(p)); // NOPMD } p = new GearmanPacketImpl(GearmanPacketMagic.REQ, getGrabJobPacketType(), new byte[0]); GearmanTask gsr = new GearmanTask(new GrabJobEventHandler(session), p); taskMap.put(session, gsr); session.submitTask(gsr); LOG.debug("Added server " + conn + " to worker " + this); return true; }
public boolean hasConnection(GearmanJobServerConnection conn) { for (GearmanJobServerSession sess : sessionsMap.values()) { if (sess.getConnection().equals(conn)) { return true; } } return false; }
public boolean hasServer(GearmanJobServerConnection conn) { boolean foundIt = false; for (GearmanJobServerSession sess : sessionMap.values()) { if (sess.getConnection().equals(conn)) { foundIt = true; } } return foundIt; }
public List<GearmanJobServerConnection> getSetOfJobServers() throws IllegalStateException { if (!runState.equals(state.RUNNING)) { throw new IllegalStateException(CLIENT_NOT_ACTIVE); } ArrayList<GearmanJobServerConnection> retSet = new ArrayList<GearmanJobServerConnection>(); for (GearmanJobServerSession sess : sessionsMap.values()) { retSet.add(sess.getConnection()); } return retSet; }
private boolean setForwardExceptions(GearmanJobServerSession session) { GearmanServerResponseHandler optionReqHandler = new GearmanServerResponseHandler() { boolean isDone = false; public boolean isDone() { return isDone; } public void handleEvent(GearmanPacket event) throws GearmanException { GearmanPacketType type = event.getPacketType(); if (type.equals(GearmanPacketType.OPTION_RES) && Arrays.equals(EXCEPTIONS, event.getData())) { isDone = true; } } }; GearmanTask setExceptionsTask = new GearmanTask( optionReqHandler, new GearmanPacketImpl( GearmanPacketMagic.REQ, GearmanPacketType.OPTION_REQ, EXCEPTIONS)); session.submitTask(setExceptionsTask); Exception e = null; boolean success = false; try { success = driveRequestTillState(setExceptionsTask, GearmanTask.State.FINISHED); } catch (IOException ioe) { e = ioe; } if (!success) { if (e != null) { LOG.info("Failed to set forward-exceptions option to " + session.getConnection(), e); } else { LOG.info("Failed to set forward-exceptions option to " + session.getConnection()); } return false; } return true; }
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); }