php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #59706 Uncaught worker exception sends back GEARMAN_SUCCESS return code.
Submitted: 2011-04-10 15:24 UTC Modified: 2011-08-20 07:41 UTC
From: hradtke@php.net Assigned: hradtke (profile)
Status: Closed Package: gearman (PECL)
PHP Version: Trunk SVN-2011-04-10 (dev) OS:
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hradtke@php.net
New email:
PHP Version: OS:

 

 [2011-04-10 15:24 UTC] hradtke@php.net
Description:
------------
The gearman worker code return GEARMAN_SUCCESS if an uncaught exception is thrown in worker callback function.

Reproduce code:
---------------
<?php
$gmworker= new GearmanWorker();
$gmworker->addServer();
$gmworker->addFunction("func", "func");

while($gmworker->work());

function func($job)
{
    throw new Exception('oww!');
}
?>

Patch:
svn diff php_gearman.c
Index: php_gearman.c
===================================================================
--- php_gearman.c       (revision 310107)
+++ php_gearman.c       (working copy)
@@ -3438,8 +3438,13 @@
                                                 worker_cb->zcall->value.str.val : "[undefined]");
                *ret_ptr= GEARMAN_WORK_FAIL;
        }
-       *ret_ptr= jobj->ret;

+       if (EG(exception)) {
+               *ret_ptr= GEARMAN_WORK_FAIL;
+       } else {
+               *ret_ptr= jobj->ret;
+       }
+
        if (zret_ptr == NULL || Z_TYPE_P(zret_ptr) == IS_NULL) {
                result= NULL;
        } else {


Expected result:
----------------
The GearmanClient::returnCode() method should return GEARMAN_WORK_FAIL.

Actual result:
--------------
The GearmanClient::returnCode() method returns GEARMAN_SUCCESS.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-04-20 07:36 UTC] craig dot lumley at everythingeverywhere dot com
If the aim of this patch is to catch exceptions properly shouldn't it be making use of the GEARMAN_WORK_EXCEPTION constant?
 [2011-04-21 01:44 UTC] hradtke@php.net
From what I have read of the Gearman protocol, it really does not deal with instances where a worker crashes.  An uncaught exception will cause the worker to terminate (crash) and I see a crash as a GEARMAN_WORK_FAIL.

My goal was not to involve the gearman extension in exception handling, but instead to inform the server and client that the result is not GEARMAN_SUCCESS.

I see GEARMAN_WORK_EXCEPTION as a tool for the worker to send a status up if certain exceptions are explicitly caught.
 [2011-04-21 06:13 UTC] craig dot lumley at everythingeverywhere dot com
I see where you're coming from and further to the post on your personal site I think we should be going down the route of correctly allowing the exceptions to bubble back up to the GearmanClient and dealing with that there. It allows much more control.

I think if no exception call back (GearmanClient::setExceptionCallback) has been set we should look at returning a fail as you have suggested. Currently as you know the exception callback isn't working as suggested by the documentation.

In the instance of what information to return back, if possible a serialized version of the exception along with the job id and/or any other information that might be useful would be the most appropriate in my opinion. What're your thoughts?

Hopefully this is the right bug report to be considering these options?

- Craig
 [2011-05-15 05:41 UTC] hradtke@php.net
Trying to get a straight answer from the libgearman guys as to whether or not GEARMAN_WORK_EXCEPTION is even supported.  If I send that status back, the client just infinite loops.
 [2011-08-20 07:41 UTC] hradtke@php.net
I have fixed this in svn.



Due to the way libgearman currently works, GEARMAN_WORK_FAIL is still sent to the client even if GEARMAN_WORK_EXCEPTION has already been sent.

This means two things:
1. GearmanClient::do() will still return GEARMAN_WORK_FAIL on an exception.
2. The fail callback will be triggered unless the exception callback sends back a return value that is not GEARMAN_SUCCESS.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Dec 04 06:01:31 2024 UTC