Browse Source

Param to skip exception handling setup in addServer/addServers in GeamanWorker class

Fixes #7
Oleg Stepanischev 3 years ago
parent
commit
deef931a30
4 changed files with 147 additions and 20 deletions
  1. 8 4
      gearman.stub.php
  2. 12 8
      gearman_arginfo.h
  3. 33 8
      php_gearman_worker.c
  4. 94 0
      tests/gearman_worker_018.phpt

+ 8 - 4
gearman.stub.php

@@ -334,10 +334,10 @@ class GearmanWorker {
     public function setId(string $id): bool {}
 
     /** @alias gearman_worker_add_server */
-    public function addServer(string $host = null, int $port = 0): bool {}
+    public function addServer(string $host = null, int $port = 0, bool $setupExceptionHandler = true): bool {}
 
     /** @alias gearman_worker_add_servers */
-    public function addServers(string $servers = null): bool {}
+    public function addServers(string $servers = null, bool $setupExceptionHandler = true): bool {}
 
     /** @alias gearman_worker_wait */
     public function wait(): bool {}
@@ -362,6 +362,9 @@ class GearmanWorker {
 
     /** @alias gearman_worker_ping */
     public function ping(string $data): bool {}
+
+    /** @alias gearman_worker_enable_exception_handler */
+    public function enableExceptionHandler(): bool {}
 }
 
 function gearman_worker_return_code(GearmanWorker $obj): ?int {}
@@ -374,8 +377,8 @@ function gearman_worker_remove_options(GearmanWorker $obj, int $option): ?bool {
 function gearman_worker_timeout(GearmanWorker $obj): ?int {}
 function gearman_worker_set_timeout(GearmanWorker $obj, int $timeout): bool {}
 function gearman_worker_set_id(GearmanWorker $obj, string $id): bool {}
-function gearman_worker_add_server(GearmanWorker $obj, string $host = null, int $port = 0): bool {}
-function gearman_worker_add_servers(GearmanWorker $obj, string $servers = null): bool {}
+function gearman_worker_add_server(GearmanWorker $obj, string $host = null, int $port = 0, bool $setupExceptionHandler = true): bool {}
+function gearman_worker_add_servers(GearmanWorker $obj, string $servers = null, bool $setupExceptionHandler = true): bool {}
 function gearman_worker_wait(GearmanWorker $obj): bool {}
 function gearman_worker_register(GearmanWorker $obj, string $function_name, int $timeout = 0): bool {}
 function gearman_worker_unregister(GearmanWorker $obj, string $function_name): bool {}
@@ -384,5 +387,6 @@ function gearman_worker_grab_job(GearmanWorker $obj): GearmanWorker|false {}
 function gearman_worker_add_function(GearmanWorker $obj, string $function_name, callable $function, ?mixed $context = null, int $timeout = 0): bool {}
 function gearman_worker_work(GearmanWorker $obj): bool {}
 function gearman_worker_ping(GearmanWorker $obj, string $data): bool {}
+function gearman_worker_enable_exception_handler(GearmanWorker $obj): bool {}
 
 class GearmanException extends Exception { }

+ 12 - 8
gearman_arginfo.h

@@ -1,5 +1,5 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 7db1ae6e6603b0be9126ceb70d68ed76646159b7 */
+ * Stub hash: bf4285b6af333c47f5d7e36723bdede63c5ddcf5 */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gearman_version, 0, 0, IS_STRING, 0)
 ZEND_END_ARG_INFO()
@@ -289,11 +289,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gearman_worker_add_server, 0, 1,
 	ZEND_ARG_OBJ_INFO(0, obj, GearmanWorker, 0)
 	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, host, IS_STRING, 0, "null")
 	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 0, "0")
+	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, setupExceptionHandler, _IS_BOOL, 0, "true")
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gearman_worker_add_servers, 0, 1, _IS_BOOL, 0)
 	ZEND_ARG_OBJ_INFO(0, obj, GearmanWorker, 0)
 	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, servers, IS_STRING, 0, "null")
+	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, setupExceptionHandler, _IS_BOOL, 0, "true")
 ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gearman_worker_wait, 0, 1, _IS_BOOL, 0)
@@ -332,6 +334,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gearman_worker_ping, 0, 2, _IS_B
 	ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
 ZEND_END_ARG_INFO()
 
+#define arginfo_gearman_worker_enable_exception_handler arginfo_gearman_worker_wait
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_GearmanClient___construct, 0, 0, 0)
 ZEND_END_ARG_INFO()
 
@@ -563,14 +567,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_GearmanWorker_setId, 0, 1,
 	ZEND_ARG_TYPE_INFO(0, id, IS_STRING, 0)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_GearmanWorker_addServer, 0, 0, _IS_BOOL, 0)
-	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, host, IS_STRING, 0, "null")
-	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 0, "0")
-ZEND_END_ARG_INFO()
+#define arginfo_class_GearmanWorker_addServer arginfo_class_GearmanClient_addServer
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_GearmanWorker_addServers, 0, 0, _IS_BOOL, 0)
-	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, servers, IS_STRING, 0, "null")
-ZEND_END_ARG_INFO()
+#define arginfo_class_GearmanWorker_addServers arginfo_class_GearmanClient_addServers
 
 #define arginfo_class_GearmanWorker_wait arginfo_class_GearmanClient_wait
 
@@ -598,6 +597,8 @@ ZEND_END_ARG_INFO()
 
 #define arginfo_class_GearmanWorker_ping arginfo_class_GearmanClient_setContext
 
+#define arginfo_class_GearmanWorker_enableExceptionHandler arginfo_class_GearmanClient_wait
+
 
 ZEND_FUNCTION(gearman_version);
 ZEND_FUNCTION(gearman_bugreport);
@@ -692,6 +693,7 @@ ZEND_FUNCTION(gearman_worker_grab_job);
 ZEND_FUNCTION(gearman_worker_add_function);
 ZEND_FUNCTION(gearman_worker_work);
 ZEND_FUNCTION(gearman_worker_ping);
+ZEND_FUNCTION(gearman_worker_enable_exception_handler);
 ZEND_METHOD(GearmanClient, __construct);
 ZEND_METHOD(GearmanClient, __destruct);
 ZEND_METHOD(GearmanJob, __destruct);
@@ -794,6 +796,7 @@ static const zend_function_entry ext_functions[] = {
 	ZEND_FE(gearman_worker_add_function, arginfo_gearman_worker_add_function)
 	ZEND_FE(gearman_worker_work, arginfo_gearman_worker_work)
 	ZEND_FE(gearman_worker_ping, arginfo_gearman_worker_ping)
+	ZEND_FE(gearman_worker_enable_exception_handler, arginfo_gearman_worker_enable_exception_handler)
 	ZEND_FE_END
 };
 
@@ -908,6 +911,7 @@ static const zend_function_entry class_GearmanWorker_methods[] = {
 	ZEND_ME_MAPPING(addFunction, gearman_worker_add_function, arginfo_class_GearmanWorker_addFunction, ZEND_ACC_PUBLIC)
 	ZEND_ME_MAPPING(work, gearman_worker_work, arginfo_class_GearmanWorker_work, ZEND_ACC_PUBLIC)
 	ZEND_ME_MAPPING(ping, gearman_worker_ping, arginfo_class_GearmanWorker_ping, ZEND_ACC_PUBLIC)
+	ZEND_ME_MAPPING(enableExceptionHandler, gearman_worker_enable_exception_handler, arginfo_class_GearmanWorker_enableExceptionHandler, ZEND_ACC_PUBLIC)
 	ZEND_FE_END
 };
 

+ 33 - 8
php_gearman_worker.c

@@ -268,7 +268,7 @@ PHP_FUNCTION(gearman_worker_set_id) {
 }
 /* }}} */
 
-/* {{{ proto bool gearman_worker_add_server(object worker [, string host [, int port ]])
+/* {{{ proto bool gearman_worker_add_server(object worker [, string host [, int port [, bool setupExceptionHandler = true]]])
    Add a job server to a worker. This goes into a list of servers than can be used to run tasks. No socket I/O happens here, it is just added to a list. */
 PHP_FUNCTION(gearman_worker_add_server) {
         zval *zobj;
@@ -276,11 +276,13 @@ PHP_FUNCTION(gearman_worker_add_server) {
         char *host = NULL;
         size_t host_len = 0;
         zend_long port = 0;
+        zend_bool setupExceptionHandler = 1;
 
-        if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|sl", &zobj,
+        if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|slb", &zobj,
                                                                 gearman_worker_ce,
                                                                 &host, &host_len,
-                                                                &port
+                                                                &port,
+                                                                &setupExceptionHandler
                                                                 ) == FAILURE) {
                 RETURN_FALSE;
         }
@@ -293,7 +295,7 @@ PHP_FUNCTION(gearman_worker_add_server) {
                 RETURN_FALSE;
         }
 
-        if (! gearman_worker_set_server_option(&(obj->worker), "exceptions", (sizeof("exceptions") - 1))) {
+        if (setupExceptionHandler && !gearman_worker_set_server_option(&(obj->worker), "exceptions", (sizeof("exceptions") - 1))) {
                 GEARMAN_EXCEPTION("Failed to set exception option", 0);
         }
 
@@ -301,17 +303,20 @@ PHP_FUNCTION(gearman_worker_add_server) {
 }
 /* }}} */
 
-/* {{{ proto bool gearman_worker_add_servers(object worker [, string servers])
+/* {{{ proto bool gearman_worker_add_servers(object worker [, string servers [, bool setupExceptionHandler = true]])
    Add a list of job servers to a worker. This goes into a list of servers that can be used to run tasks. No socket I/O happens here, it is just added to a list. */
 PHP_FUNCTION(gearman_worker_add_servers) {
         zval *zobj;
         gearman_worker_obj *obj;
         char *servers = NULL;
         size_t servers_len = 0;
+        zend_bool setupExceptionHandler = 1;
 
-        if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &zobj,
+        if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|sb", &zobj,
                                                                 gearman_worker_ce,
-                                                                &servers, &servers_len
+                                                                &servers,
+                                                                &servers_len,
+                                                                &setupExceptionHandler
                                                                 ) == FAILURE) {
                 RETURN_FALSE;
         }
@@ -325,7 +330,7 @@ PHP_FUNCTION(gearman_worker_add_servers) {
                 RETURN_FALSE;
         }
 
-        if (! gearman_worker_set_server_option(&(obj->worker), "exceptions", (sizeof("exceptions") - 1))) {
+        if (setupExceptionHandler && !gearman_worker_set_server_option(&(obj->worker), "exceptions", (sizeof("exceptions") - 1))) {
                 GEARMAN_EXCEPTION("Failed to set exception option", 0);
         }
 
@@ -677,3 +682,23 @@ PHP_FUNCTION(gearman_worker_ping) {
 	RETURN_TRUE;
 }
 /* }}} */
+
+/* {{{ proto bool GearmanWorker::enableExceptionHandler()
+   Enable exception handling to be used by exception callback function
+   GearmanWorker::enableExceptionHandler */
+PHP_FUNCTION(gearman_worker_enable_exception_handler) {
+        gearman_worker_obj *obj;
+        zval *zobj;
+
+        if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &zobj, gearman_worker_ce) == FAILURE) {
+            RETURN_FALSE;
+        }
+        obj = Z_GEARMAN_WORKER_P(zobj);
+
+        if (!gearman_worker_set_server_option(&(obj->worker), "exceptions", (sizeof("exceptions") - 1))) {
+            GEARMAN_EXCEPTION("Failed to set exception option", 0);
+        }
+
+        RETURN_TRUE;
+}
+/* }}} */

+ 94 - 0
tests/gearman_worker_018.phpt

@@ -0,0 +1,94 @@
+--TEST--
+GearmanWorker::enableExceptionHandler(),gearman_worker_enable_exception_handler()
+--SKIPIF--
+<?php if (!extension_loaded("gearman")) print "skip"; ?>
+--FILE--
+<?php 
+
+// Test 1: GearmanWorker::addServers, Exception callback disabled. Exceptions
+// should be skipped until we call enableExceptionHandler. Port 4731 is not
+// being used as the port for GearmanD, so it will fail
+$worker = new GearmanWorker();
+$worker->addServers('localhost:4731,localhost', false);
+
+// Enabling the exception handler, which will attempt to connect to
+// the server and in doing so throw an exception since we can't
+// connect to a server that doesn't exist
+try {
+	$worker->enableExceptionHandler();
+} catch (Exception $e) {
+	print "Exception 1 caught: " . $e->getMessage() . PHP_EOL;
+}
+
+// Test 2: GearmanWorker::addServers,  Exception callback enabled (by default).
+// Here, we don't give the second param, so the exception handler is enabled
+// upon calling addServers instead of later in enableExceptionHandler
+$worker2 = new GearmanWorker();
+
+try {
+	$worker2->addServers('localhost:4731,localhost');
+} catch (Exception $e) {
+	print "Exception 2 caught: " . $e->getMessage() . PHP_EOL;
+}
+
+// Test 3: GearmanWorker::addServers, Also, when we explicitly enable in addServers
+$worker3 = new GearmanWorker();
+
+try {
+	$worker3->addServers('localhost:4731,localhost', true);
+} catch (Exception $e) {
+	print "Exception 3 caught: " . $e->getMessage() . PHP_EOL;
+}
+
+// Now, do the same as above but with addServer (singular)
+// Test 4: GearmanWorker::addServer, Exception callback disabled
+$worker4 = new GearmanWorker();
+$worker4->addServer('localhost', 4731, false);
+
+try {
+	$worker4->enableExceptionHandler();
+} catch (Exception $e) {
+	print "Exception 4 caught: " . $e->getMessage() . PHP_EOL;
+}
+
+// Test 5: GearmanWorker::addServer, default
+$worker5 = new GearmanWorker();
+
+try {
+	$worker5->addServer('localhost', 4731);
+} catch (Exception $e) {
+	print "Exception 5 caught: " . $e->getMessage() . PHP_EOL;
+}
+
+// Test 6: GearmanWorker::addServer, explicitly set enableExceptionHandler
+$worker6 = new GearmanWorker();
+
+try {
+	$worker6->addServer('localhost', 4731, true);
+} catch (Exception $e) {
+	print "Exception 6 caught: " . $e->getMessage() . PHP_EOL;
+}
+
+// Test 7: GearmanWorker::addServer, default (positive case)
+$worker7 = new GearmanWorker();
+$worker7->addServer('localhost', 4730);
+
+// Test 8: GearmanWorker::addServer, explicitly set enableExceptionHandler (positive case)
+$worker8 = new GearmanWorker();
+$worker8->addServer('localhost', 4730, true);
+
+// Test 9: GearmanWorker::addServer, call enableExceptionHandler (positive case)
+$worker9 = new GearmanWorker();
+$worker9->addServer('localhost', 4730, false);
+$worker9->enableExceptionHandler();
+
+print "OK";
+?>
+--EXPECTF--
+Exception 1 caught: Failed to set exception option
+Exception 2 caught: Failed to set exception option
+Exception 3 caught: Failed to set exception option
+Exception 4 caught: Failed to set exception option
+Exception 5 caught: Failed to set exception option
+Exception 6 caught: Failed to set exception option
+OK