Browse Source

Updates for handling exceptions.

Brian Aker 12 years ago
parent
commit
3f1f7f2282

+ 1 - 0
ChangeLog

@@ -2,6 +2,7 @@
 * Merge of 1.0.4 tree
 * Added support for gearadmin to "cancel" a job.
 * Keep-alive support for gearmand has been extended (more options to control behavior).
+* Fixed issues related to clients who didn't really support exceptions being passed exceptions.
 
 1.1.5 Mon Feb  4 00:59:19 EST 2013
 * Rollup of bug fixes for 1.0.3

+ 1 - 1
gearmand/gearmand.cc

@@ -142,7 +142,7 @@ int main(int argc, char *argv[])
   ("daemon,d", boost::program_options::bool_switch(&opt_daemon)->default_value(false),
    "Daemon, detach and run in the background.")
 
-  ("exceptions", boost::program_options::bool_switch(&opt_exceptions)->default_value(true),
+  ("exceptions", boost::program_options::bool_switch(&opt_exceptions)->default_value(false),
    "Enable protocol exceptions by default.")
 
   ("file-descriptors,f", boost::program_options::value(&fds),

+ 1 - 1
libgearman-1.0/protocol.h

@@ -69,7 +69,7 @@ enum gearman_command_t
   GEARMAN_COMMAND_SET_CLIENT_ID,       /* W->J: [RANDOM_STRING_NO_WHITESPACE] */
   GEARMAN_COMMAND_CAN_DO_TIMEOUT,      /* W->J: FUNC[0]TIMEOUT */
   GEARMAN_COMMAND_ALL_YOURS,
-  GEARMAN_COMMAND_WORK_EXCEPTION,
+  GEARMAN_COMMAND_WORK_EXCEPTION,      /* W->J/C: HANDLE[0] */
   GEARMAN_COMMAND_OPTION_REQ,          /* ?->J: TEXT */
   GEARMAN_COMMAND_OPTION_RES,          /* J->?: TEXT */
   GEARMAN_COMMAND_WORK_DATA,

+ 1 - 0
libgearman-1.0/string.h

@@ -45,6 +45,7 @@ struct gearman_string_t {
 
 #define gearman_size(X) (X).size
 #define gearman_c_str(X) (X).c_str
+#define gearman_string_param_printf(X) int((X).size), (X).c_str
 #define gearman_string_param(X) (X).c_str, (X).size
 #define gearman_string_param_null NULL, 0
 #define gearman_string_param_cstr(X) (X), ((X) ? strlen(X) : 0)

+ 6 - 0
libgearman-1.0/task.h

@@ -170,6 +170,12 @@ gearman_return_t gearman_task_return(const gearman_task_st *task);
 GEARMAN_API
 const char *gearman_task_strstate(const gearman_task_st *);
 
+GEARMAN_API
+bool gearman_task_has_exception(const gearman_task_st* task_shell);
+
+GEARMAN_API
+gearman_string_t gearman_task_exception(const gearman_task_st *);
+
 /** @} */
 
 #ifdef __cplusplus

+ 4 - 4
libgearman-server/server.cc

@@ -998,7 +998,7 @@ _server_queue_work_data(gearman_server_job_st *server_job,
   for (server_client= server_job->client_list; server_client;
        server_client= server_client->job_next)
   {
-    if (command == GEARMAN_COMMAND_WORK_EXCEPTION && !(server_client->con->is_exceptions))
+    if (command == GEARMAN_COMMAND_WORK_EXCEPTION and (server_client->con->is_exceptions == false))
     {
       gearmand_debug("Dropping GEARMAN_COMMAND_WORK_EXCEPTION");
       continue;
@@ -1034,9 +1034,9 @@ _server_queue_work_data(gearman_server_job_st *server_job,
     }
 
     gearmand_error_t ret= gearman_server_io_packet_add(server_client->con, true,
-                                      GEARMAN_MAGIC_RESPONSE, command,
-                                      packet->arg[0], packet->arg_size[0],
-                                      data, packet->data_size, NULL);
+                                                       GEARMAN_MAGIC_RESPONSE, command,
+                                                       packet->arg[0], packet->arg_size[0],
+                                                       data, packet->data_size, NULL);
     if (ret != GEARMAN_SUCCESS)
     {
       gearmand_gerror("gearman_server_io_packet_add", ret);

+ 1 - 0
libgearman/interface/task.hpp

@@ -80,6 +80,7 @@ struct Task
   gearman_return_t result_rc;
   struct gearman_result_st *_result_ptr;
   char job_handle[GEARMAN_JOB_HANDLE_SIZE];
+  gearman_vector_st exception;
   size_t unique_length;
   char unique[GEARMAN_MAX_UNIQUE_SIZE];
 

+ 5 - 0
libgearman/run.cc

@@ -355,6 +355,11 @@ gearman_return_t _client_run_task(Task *task)
     else if (task->recv->command == GEARMAN_COMMAND_WORK_EXCEPTION)
     {
   case GEARMAN_TASK_STATE_EXCEPTION:
+      if (task->recv->argc == 1 and task->recv->data_size)
+      {
+        task->exception.store((const char*)(task->recv->data), task->recv->data_size);
+      }
+
       if (task->func.exception_fn)
       {
         gearman_return_t ret= task->func.exception_fn(task->shell());

+ 31 - 1
libgearman/task.cc

@@ -72,7 +72,7 @@ gearman_task_st *gearman_task_internal_create(gearman_client_st& client, gearman
 
 void gearman_task_free(gearman_task_st *task_shell)
 {
-  if (task_shell)
+  if (task_shell and task_shell->impl())
   {
     if (gearman_is_initialized(task_shell))
     {
@@ -125,6 +125,8 @@ void gearman_task_free(gearman_task_st *task_shell)
 
         gearman_set_initialized(task, false);
 
+        task_shell->_impl= NULL;
+
         delete task;
       }
     }
@@ -442,3 +444,31 @@ bool Task::create_result(size_t initial_size)
   _result_ptr= new (std::nothrow) gearman_result_st(initial_size);
   return bool(_result_ptr);
 }
+
+bool gearman_task_has_exception(const gearman_task_st* task_shell)
+{
+  if (task_shell and task_shell->impl())
+  {
+    if (task_shell->impl()->exception.empty() == false)
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+gearman_string_t gearman_task_exception(const gearman_task_st* task_shell)
+{
+  if (task_shell and task_shell->impl())
+  {
+    if (task_shell->impl()->exception.empty() == false)
+    {
+      gearman_string_t ret= { task_shell->impl()->exception.value(), task_shell->impl()->exception.size() };
+      return ret;
+    }
+  }
+
+  static gearman_string_t ret= {0, 0};
+  return ret;
+}

+ 1 - 0
libgearman/vector.cc

@@ -60,6 +60,7 @@ inline static bool _string_check(gearman_vector_st *string, const size_t need)
   assert_msg(string, "Programmer error, _string_check() was passed a null gearman_vector_st");
   if (string)
   {
+    assert(string->end >= string->string);
     if (need and need > size_t(string->current_size - size_t(string->end - string->string)))
     {
       size_t current_offset= size_t(string->end - string->string);

Some files were not shown because too many files changed in this diff