/// <summary> /// Submit a job to a job server for processing. The callback string is used as the /// task for the manager to hand off the job to a worker. /// </summary> /// <param name="callback"> /// A string containing the name of the operation to ask the manager to find a worker for /// </param> /// <param name="data"> /// A byte array containing the data to be worked on. This data is passed to the worker who can /// work on a job of the requested type. /// </param> /// <returns> /// A byte array containing the response from the worker that completed the task /// </returns> /// <example> /// <code> /// Client c = new Client("localhost"); /// byte[] data = new ASCIIEncoding().GetBytes("foo\nbar\nquiddle\n"); /// byte[] result = c.submitJob("wc", data); /// </code> /// </example> public byte[] submitJob(string callback, byte[] data) { try { Packet result = null; bool submitted = false; Connection c = null; string jobid = System.Guid.NewGuid().ToString(); SubmitJob p = new SubmitJob(callback, jobid, data, false); while (!submitted) { // Simple round-robin submission for now c = managers[connectionIndex++ % managers.Count]; c.sendPacket(p); Log.DebugFormat("Sent job request to {0}...", c); // We need to get back a JOB_CREATED packet result = c.getNextPacket(); // If we get back a JOB_CREATED packet, we can continue // otherwise try the next job manager if (result.Type == PacketType.JOB_CREATED) { submitted = true; Log.DebugFormat("Created job {0}", ((JobCreated)result).jobhandle); } } // This method handles synchronous requests, so we wait // until we get a work complete packet while (true) { result = c.getNextPacket(); if (result.Type == PacketType.WORK_COMPLETE) { WorkComplete wc = (WorkComplete)result; Log.DebugFormat("Completed job {0}", wc.jobhandle); return(wc.data); } } } catch (Exception e) { Log.DebugFormat("Error submitting job: {0}", e.ToString()); return(null); } }
/// <summary> /// Checks with the manager for a new job to work on. The manager has a record of all the tasks that the /// worker is capable of working on, so most of the real work here is done by the manager to find something /// for the worker to work on. If something is assigned, load the data, execute the callback and then return /// the data to the manager so that the worker can move on to something else. /// </summary> private void checkForJob() { ASCIIEncoding encoder = new ASCIIEncoding(); // Grab job from server (if available) Log.DebugFormat("Checking for job..."); c.sendPacket(new GrabJob()); Packet response = c.getNextPacket(); if (response.Type == PacketType.JOB_ASSIGN) { Job job = new Job((JobAssign)response, this); Log.DebugFormat("Assigned job: {0}", job.jobhandle); Log.DebugFormat("Payload length: {0}", job.data.Length); Log.DebugFormat("Task: {0}", job.taskname); // Fire event for listeners methodMap[job.taskname](job); } else if (response.Type == PacketType.NO_JOB) { Log.DebugFormat("Nothing to do!"); } }
/// <summary>Submit a job to the job server in the background, with a particular priority</summary> /// <example> /// <code> /// </code> /// </example> public string submitJobInBackground(string callback, byte[] data, JobPriority priority) { try { Connection c = null; string jobid = System.Guid.NewGuid().ToString(); SubmitJob p = new SubmitJob(callback, jobid, data, true, priority); Packet result; while (true) { // Simple round-robin submission for now c = managers[connectionIndex++ % managers.Count]; c.sendPacket(p); Log.DebugFormat("Sent background job request to {0}...", c); // We need to get back a JOB_CREATED packet result = c.getNextPacket(); // If we get back a JOB_CREATED packet, we can continue, // otherwise try the next job manager if (result.Type == PacketType.JOB_CREATED) { Log.DebugFormat("Created background job {0}, with priority {1}", ((JobCreated)result).jobhandle, priority.ToString()); return(((JobCreated)result).jobhandle); } } } catch (Exception e) { Log.DebugFormat("Error submitting job: {0}", e.ToString()); return(null); } }
private void run() { Packet p; bool okay = true; while (okay) { p = conn.getNextPacket(); if (p != null) { //p.Dump(); // Immediately store background jobs and move on switch (p.Type) { case PacketType.SUBMIT_JOB: handleJobSubmitted(p, JobPriority.NORMAL, false); break; case PacketType.SUBMIT_JOB_HIGH: handleJobSubmitted(p, JobPriority.HIGH, false); break; case PacketType.SUBMIT_JOB_LOW: handleJobSubmitted(p, JobPriority.LOW, false); break; case PacketType.SUBMIT_JOB_BG: handleJobSubmitted(p, JobPriority.NORMAL, true); break; case PacketType.SUBMIT_JOB_HIGH_BG: handleJobSubmitted(p, JobPriority.HIGH, true); break; case PacketType.SUBMIT_JOB_LOW_BG: handleJobSubmitted(p, JobPriority.LOW, true); break; case PacketType.SUBMIT_JOB_EPOCH: handleJobSubmitted(p, JobPriority.NORMAL, true); break; case PacketType.SUBMIT_JOB_SCHED: handleJobSubmitted(p, JobPriority.NORMAL, true); break; case PacketType.GRAB_JOB: p.Dump(); grabNextJob(); break; case PacketType.CAN_DO: p.Dump(); registerAbility(p); break; case PacketType.SET_CLIENT_ID: p.Dump(); break; case PacketType.WORK_COMPLETE: handleJobCompletion(p); break; case PacketType.WORK_FAIL: handleJobCompletion(p); break; case PacketType.WORK_EXCEPTION: handleJobCompletion(p); break; case PacketType.PRE_SLEEP: p.Dump(); GearmanServer.Log.Debug("Worker sleeping..."); break; default: GearmanServer.Log.Info("Nothing to do with this..."); break; } } else { GearmanServer.Log.Info("No packet!"); okay = false; } } GearmanServer.Log.Info("ConnectionHandler terminated."); foreach (String funcName in workers.Keys) { GearmanServer.Log.Info("Removing connection from worker list"); workers[funcName].Remove(this.conn); } }