public GearmanJob(GearmanWorkerProtocol protocol, GearmanJobInfo jobAssignment, DataDeserializer <TArg> argumentDeserializer, DataSerializer <TResult> resultSerializer) { _serializer = resultSerializer; _deserializer = argumentDeserializer; _protocol = protocol; Info = jobAssignment; FunctionArgument = _deserializer(jobAssignment.FunctionArgument); }
protected bool Work(IGearmanConnection connection) { try { var protocol = new GearmanWorkerProtocol(connection); var jobAssignment = protocol.GrabJob(); if (jobAssignment == null) { return(false); } if (!_functionInformation.ContainsKey(jobAssignment.FunctionName)) { throw new GearmanApiException(String.Format("Received work for unknown function {0}", jobAssignment.FunctionName)); } CallFunction(protocol, jobAssignment); return(true); } catch (GearmanConnectionException) { connection.MarkAsDead(); return(false); } catch (GearmanFunctionInternalException functionException) { // The job function threw an exception. Just as with other exceptions, we disconnect // from the server because we don't want the job to be removed. See general exception // catch for more information. connection.Disconnect(); var shouldThrow = OnJobException(functionException.InnerException, functionException.JobInfo); if (shouldThrow) { throw; } return(false); } catch (Exception) { // We failed to call the function and there isn't any good response to send the server. // According to this response on the mailing list, the best action is probably to close the connection: // "A worker disconnect with no response message is currently how the server's retry behavior is triggered." // http://groups.google.com/group/gearman/browse_thread/thread/5c91acc31bd10688/529e586405ed37fe // // We can't send Complete or Fail for the job, because that would cause the job to be "done" and the server wouldn't retry. connection.Disconnect(); throw; } }
private void CallFunction(GearmanWorkerProtocol protocol, GearmanJobInfo jobAssignment) { var functionInformation = _functionInformation[jobAssignment.FunctionName]; object job; try { job = functionInformation.JobConstructor.Invoke(new object[] { protocol, jobAssignment, functionInformation.ArgumentDeserializer, functionInformation.ResultSerializer, }); } catch (Exception ex) { throw new GearmanException("Failed to invoke the GearmanJob constructor", ex); } try { functionInformation.Function.DynamicInvoke(job); } catch (TargetInvocationException ex) { if (ex.InnerException != null) { // Remove the TargetInvocationException wrapper that DynamicInvoke added, // so we can give the user the exception from the job function. throw new GearmanFunctionInternalException( jobAssignment, String.Format("Function '{0}' threw exception", jobAssignment.FunctionName), ex.InnerException); } // If there is no inner exception, something strange is up, so then we want to throw this exception. throw new GearmanException("Failed to invoke the function dynamically", ex); } catch (Exception ex) { throw new GearmanException("Failed to invoke the function dynamically", ex); } }