private final void work_status(final GearmanPacket packet, final ServerClient client) { /* * This is sent to update the server (and any listening clients) * of the status of a running job. The client should send these * periodically for long running jobs to update the percentage * complete. The job server should store this information so a client * who issued a background command may retrieve it later with a * GET_STATUS request. * * Arguments: * - NULL byte terminated job handle. * - NULL byte terminated percent complete numerator. * - Percent complete denominator. */ final byte[] jobHandle = packet.getArgumentData(0); assert jobHandle != null; final ByteArray jobHandleBA = new ByteArray(jobHandle); final byte[] num = packet.getArgumentData(1); assert num != null; final byte[] den = packet.getArgumentData(2); assert den != null; final ServerJob job = ServerJobAbstract.getJob(jobHandleBA); if (job == null) { client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/); } else { packet.setMagic(Magic.RES); job.setStatus(num, den); job.sendPacket(packet); } }
private final void work_data(final GearmanPacket packet, final ServerClient client) { /* * This is sent to update the client with data from a running job. A * client should use this when it needs to send updates, send partial * results, or flush data during long running jobs. It can also be * used to break up a result so the client does not need to buffer * the entire result before sending in a WORK_COMPLETE packet. * * Arguments: * - NULL byte terminated job handle. * - Opaque data that is returned to the client. */ final byte[] jobHandle = packet.getArgumentData(0); assert jobHandle != null; final ByteArray jobHandleBA = new ByteArray(jobHandle); final ServerJob job = ServerJobAbstract.getJob(jobHandleBA); if (job == null) { client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/); } else { packet.setMagic(Magic.RES); job.sendPacket(packet); } }
/** * Called when a text-based packet is received. When a packet with type -1 is received, it's * assumed to be a text-based packet. The first argument (The command argument in a text-based * packet) is checked against the set of known commands. Then, the command is executed or an * exception is returned to the client if the command is unknown. * * @param packet The received packet with a type of -1 * @param client The client who received the packet */ private final void text_packet(final GearmanPacket packet, final ServerClient client) { final String pkt = new String(packet.toBytes(), GearmanConstants.UTF_8); final String[] args = pkt.trim().split("[ \t]"); if (args[0].equalsIgnoreCase("workers")) { text_workers(args, client); return; } else if (args[0].equalsIgnoreCase("status")) { text_status(args, client); return; } else if (args[0].equalsIgnoreCase("maxqueue")) { text_maxqueue(args, client); return; } else if (args[0].equalsIgnoreCase("shutdown")) { text_shutdown(args, client); return; } else if (args[0].equalsIgnoreCase("version")) { text_version(args, client); return; } else if (args[0].equalsIgnoreCase("throttle")) { update_throttle(args, client); return; } else if (args[0].equalsIgnoreCase("memstats")) { getMemStats(client); return; } else if (args[0].equalsIgnoreCase("workertime")) { worker_time_status(args, client); return; } else { client.sendPacket(ServerStaticPackets.TEXT_UNKNOWN_COMMAND, null /*TODO*/); } }
private final void option_req(final GearmanPacket packet, final ServerClient client) { /* * A client issues this to set an option for the connection in the * job server. Returns a OPTION_RES packet on success, or an ERROR * packet on failure. * * Arguments: * - Name of the option to set. Possibilities are: * "exceptions" - Forward WORK_EXCEPTION packets to the client. */ final byte[] option = packet.getArgumentData(0); assert option != null; final byte[] exceptions = new byte[] {'e', 'x', 'c', 'e', 'p', 't', 'i', 'o', 'n', 's'}; if (Arrays.equals(option, exceptions)) { // exceptions option client.setForwardsExceptions(true); client.sendPacket(ServerStaticPackets.OPTION_RES_EXCEPTIONS, null /*TODO*/); } else { // unknown option client.sendPacket(ServerStaticPackets.ERROR_UNKNOWN_OPTION, null /*TODO*/); } }
private final void get_status(final GearmanPacket packet, final ServerClient client) { /* * A client issues this to get status information for a submitted job. * * Arguments: * - Job handle that was given in JOB_CREATED packet. */ final byte[] jobHandle = packet.getArgumentData(0); assert jobHandle != null; final ByteArray jobHandleBA = new ByteArray(jobHandle); final ServerJob job = ServerJobAbstract.getJob(jobHandleBA); if (job == null) { // Send unknown job STATUS_RES packet final byte[] unknown = new byte[] {'0'}; final GearmanPacket status_res = new GearmanPacket( Magic.RES, Type.STATUS_RES, jobHandle, unknown, unknown, unknown, unknown); client.sendPacket(status_res, null /*TODO*/); return; } final GearmanPacket status = job.createStatusResPacket(); client.sendPacket(status, null /*TODO*/); }
private final void submit_job( final GearmanPacket packet, final ServerClient client, ServerJob.JobPriority priority, boolean isBackground) { /* * A client issues this when a job needs to be run. The server will * then assign a job handle and respond with a JOB_CREATED packet. * * If on of the BG versions is used, the client is not updated with * status or notified when the job has completed (it is detached). * * The Gearman job server queue is implemented with three levels: * normal, high, and low. Jobs submitted with one of the HIGH versions * always take precedence, and jobs submitted with the normal versions * take precedence over the LOW versions. * * Arguments: * - NULL byte terminated function name. * - NULL byte terminated unique ID. * - Opaque data that is given to the function as an argument. */ // Argument: function name final byte[] funcName = packet.getArgumentData(0); assert funcName != null; final ByteArray funcNameBA = new ByteArray(funcName); // Argument: unique ID final byte[] uniqueID = packet.getArgumentData(1); assert uniqueID != null; final ByteArray uniqueIDBA = new ByteArray(uniqueID); // Argument: data final byte[] data = packet.getArgumentData(2); assert data != null; /* * FWIX CHANGE */ // final ServerFunction func = this.funcSetHigh.getFunction(funcNameBA); funcSet.createJob(funcNameBA, uniqueIDBA, data, priority, client, isBackground); }
private final void work_exception(final GearmanPacket packet, final ServerClient client) { /* * This is to notify the server (and any listening clients) that * the job failed with the given exception. * * Arguments: * - NULL byte terminated job handle. * - Opaque data that is returned to the client as an exception. */ // Note: The protocol states this packet notifies the server that the specified job // has failed. However, the C server does not fail the Job. It is effectively a // WORK_WARNING packet that is only sent to clients that have specified they want // exceptions forwarded to them. This server will do the same as long as the C // server does so. /* * This is sent to update the client with data from a running job. A * client should use this when it needs to send updates, send partial * results, or flush data during long running jobs. It can also be * used to break up a result so the client does not need to buffer * the entire result before sending in a WORK_COMPLETE packet. * * Arguments: * - NULL byte terminated job handle. * - Opaque data that is returned to the client. */ final byte[] jobHandle = packet.getArgumentData(0); ; assert jobHandle != null; final ByteArray jobHandleBA = new ByteArray(jobHandle); final ServerJob job = ServerJobAbstract.getJob(jobHandleBA); if (job == null) { client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/); } else { packet.setMagic(Magic.RES); job.sendPacket(packet); } }
private final void echo_req(final GearmanPacket packet, final ServerClient client) { /* * When a job server receives this request, it simply generates a * ECHO_RES packet with the data. This is primarily used for testing * or debugging. * * Arguments: * - Opaque data that is echoed back in response. */ packet.setMagic(Magic.RES); client.sendPacket(packet, null /*TODO*/); }
public void getMemStats(final ServerClient client) { StringBuilder sb = new StringBuilder(); sb.append(Main.memUsed()); sb.append('\t'); sb.append(Main.getThreadCount()); sb.append('\t'); sb.append(Main.getActiveThreadCount()); sb.append('\t'); sb.append(Main.getUpTime()); sb.append('\n'); client.sendPacket(GearmanPacket.createTEXT(sb.toString()), null /*TODO*/); return; }
/** * Called when a CANT_DO packet comes in.<br> * <br> * <i> This is sent to notify the server that the client is no longer able to perform the given * function.<br> * <br> * Arguments:<br> * - Function name.<br> * </i> * * @param packet The CANT_DO packet * @param client The client who aquired the packet */ private final void cant_do(final GearmanPacket packet, final ServerClient client) { /* * This is sent to notify the server that the client is no longer able to * perform the given function. * * Arguments: * - Function name. */ // Function Name final byte[] funcName = packet.getArgumentData(0); assert funcName != null; if (funcName.length == 0) { // TODO send error } client.cant_do(new ByteArray(funcName)); }
/** * Called when a CAN_DO packet comes in.<br> * <br> * <i> CAN_DO:<br> * This is sent to notify the server that the client is able to perform the given function. The * client is then put on a list to be waken up whenever the job server receives a job for that * function.<br> * <br> * Arguments:<br> * - Function name.<br> * </i> * * @param packet The CAN_DO packet * @param client The client who acquired the packet. */ private final void can_do(final GearmanPacket packet, final ServerClient client) { // Note: Currently the CAN_DO_TIMEOUT maps to this method, the timeout // feature will be fully implemented in the future. // Function Name final byte[] funcName = packet.getArgumentData(0); assert funcName != null; if (funcName.length == 0) { // TODO send error } ByteArray funcNameBA = new ByteArray(funcName); // funcNameBA = GMServerFunctionMap.GM_TASK_BA; funcSet.registerClient(funcNameBA, client); }
private final void work_fail(final GearmanPacket packet, final ServerClient client) { /* * This is to notify the server (and any listening clients) that * the job failed. * * Arguments: * - Job handle. */ final byte[] jobHandle = packet.getArgumentData(0); assert jobHandle != null; final ByteArray jobHandleBA = new ByteArray(jobHandle); final ServerJob job = ServerJobAbstract.getJob(jobHandleBA); if (job == null) { client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/); } else { job.workComplete(packet); } }
private final void set_client_id(final GearmanPacket packet, final ServerClient client) { /* * This sets the client ID in a job server so monitoring and reporting * commands can uniquely identify the various clients, and different * connections to job servers from the same client. * * Arguments: * - Unique string to identify the client instance. */ // Get Client ID from packet final byte[] clientIdBytes = packet.getArgumentData(0); assert clientIdBytes != null; // Convert the worker ID into a String final String clientId = new String(clientIdBytes, GearmanConstants.UTF_8); // Set the client's client ID client.setClientId(clientId); }
public void update_throttle( final String[] args, final ServerClient client) { // String function, Integer throttle){ String function = args[1]; Integer throttle = 0; StringBuilder sb = new StringBuilder(); if (args[2].equalsIgnoreCase("NOTHROTTLE")) { System.out.println("REMOVE THROTTLE" + function); Main.removeThrottle(function); sb.append(function); sb.append('\t'); sb.append("remove throttle"); sb.append('\n'); } else if (args[2].equalsIgnoreCase("KILL")) { System.out.println("KILL FUNCTION"); RemoveClass remove = new RemoveClass(function); Thread t = new Thread(remove); t.start(); sb.append(function); sb.append('\t'); sb.append("kill"); sb.append('\n'); } else { throttle = Integer.parseInt(args[2]); ; if (throttle != null && throttle >= 0) { System.out.println("Putthing throttle: " + throttle + " for function " + function); Main.setThrottle(function, throttle); sb.append(function); sb.append('\t'); sb.append(throttle); sb.append('\n'); } } client.sendPacket(GearmanPacket.createTEXT(sb.toString()), null /*TODO*/); return; }
private final void work_complete(final GearmanPacket packet, final ServerClient client) { /* * This is to notify the server (and any listening clients) that * the job completed successfully. * * Arguments: * - NULL byte terminated job handle. * - Opaque data that is returned to the client as a response. */ final byte[] jobHandle = packet.getArgumentData(0); assert jobHandle != null; final ByteArray jobHandleBA = new ByteArray(jobHandle); final ServerJob job = ServerJobAbstract.getJob(jobHandleBA); if (job == null) { client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/); } else { // Construct a WORK_COMPLETE response packet client.jobCOmplete(); job.workComplete(packet); } }
/** * Once a packet has been acquired from a client, it's processed here. The packet is processed in * compliance with the gearman protocol. * * @param packet The packet sent by the client * @param client The client associated with the client that sent the packet */ public final void execute(final GearmanPacket packet, final ServerClient client) { switch (packet.getPacketType()) { // Text Packets case TEXT: text_packet(packet, client); return; // Binary Packets case CAN_DO: can_do(packet, client); return; case CAN_DO_TIMEOUT: can_do(packet, client); return; case CANT_DO: cant_do(packet, client); return; case ECHO_REQ: echo_req(packet, client); return; case GET_STATUS: get_status(packet, client); return; case GRAB_JOB: grab_job(packet, client); return; case GRAB_JOB_UNIQ: grab_job_uniq(packet, client); return; case OPTION_REQ: option_req(packet, client); return; case PRE_SLEEP: pre_sleep(packet, client); return; case RESET_ABILITIES: System.out.println("New worker has joined"); reset_abilities(packet, client); return; case SET_CLIENT_ID: set_client_id(packet, client); return; case SUBMIT_JOB: submit_job(packet, client, ServerJob.JobPriority.MID, false); return; case SUBMIT_JOB_BG: submit_job(packet, client, ServerJob.JobPriority.MID, true); return; case SUBMIT_JOB_HIGH: submit_job(packet, client, ServerJob.JobPriority.HIGH, false); return; case SUBMIT_JOB_HIGH_BG: submit_job(packet, client, ServerJob.JobPriority.HIGH, true); return; case SUBMIT_JOB_LOW: submit_job(packet, client, ServerJob.JobPriority.LOW, false); return; case SUBMIT_JOB_LOW_BG: submit_job(packet, client, ServerJob.JobPriority.LOW, true); return; case WORK_COMPLETE: work_complete(packet, client); return; case WORK_DATA: case WORK_WARNING: work_data(packet, client); return; case WORK_EXCEPTION: work_exception(packet, client); return; case WORK_FAIL: work_fail(packet, client); return; case WORK_STATUS: work_status(packet, client); return; // Response Only Packets case NOOP: case JOB_CREATED: case NO_JOB: case ECHO_RES: case ERROR: case STATUS_RES: case OPTION_RES: case JOB_ASSIGN: case JOB_ASSIGN_UNIQ: // Packets Not Yet Implemented case ALL_YOURS: case SUBMIT_JOB_EPOCH: case SUBMIT_JOB_SCHED: client.sendPacket(ServerStaticPackets.ERROR_BAD_COMMAND, null /*TODO*/); return; // Unknown Command default: client.sendPacket(ServerStaticPackets.ERROR_BAD_COMMAND, null /*TODO*/); return; } }