php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #60814 Result not sent to client if worker exits immediately after calling work()
Submitted: 2012-01-19 22:05 UTC Modified: 2012-08-15 15:18 UTC
From: jon dot tai at gmail dot com Assigned: hradtke (profile)
Status: Closed Package: gearman (PECL)
PHP Version: 5.3.9 OS: CentOS
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: jon dot tai at gmail dot com
New email:
PHP Version: OS:

 

 [2012-01-19 22:05 UTC] jon dot tai at gmail dot com
Description:
------------
If a gearman worker process exits immediately after calling GearmanWorker-
>work() (i.e., if work() is the last call in the PHP script), the result is 
sometimes not sent back to the client.

Adding a sleep(1) after the call to work() seems to fix the issue.

I can reliably reproduce this using these steps and the test scripts described 
below.

1. Run the reverse_worker.php script
2. In another terminal, run the reverse_client.php script

This was tested on CentOS 6, php 5.3.9, libgearman/gearmand 0.27, gearman PECL 
extension 1.0.1.

This was also tested on CentOS 5, php 5.3.3, libgearman/gearmand 0.24, gearman 
PECL extension 0.8.0.

Test script:
---------------
reverse_client.php is same as distributed with PECL extension. Modified reverse_worker.php is as follows:

--- reverse_worker.php  2011-12-05 11:41:40.000000000 -0500
+++ reverse_worker.php  2012-01-19 16:56:48.521659841 -0500
@@ -23,13 +23,10 @@
 $gmworker->addFunction("reverse", "reverse_fn");

 print "Waiting for job...\n";
-while($gmworker->work())
-{
+$gmworker->work();
   if ($gmworker->returnCode() != GEARMAN_SUCCESS)
   {
     echo "return_code: " . $gmworker->returnCode() . "\n";
-    break;
-  }
 }

Expected result:
----------------
The reverse_worker script should print:

Starting
Waiting for job...
Received job: H:ip-10-114-41-34:33
Workload: Hello! (6)
Sending status: 0/6 complete
Sending status: 1/6 complete
Sending status: 2/6 complete
Sending status: 3/6 complete
Sending status: 4/6 complete
Sending status: 5/6 complete
Result: !olleH

The reverse_client script should print:

Starting
Sending job
Success: !olleH

Actual result:
--------------
As expected, the reverse_worker script prints:

Starting
Waiting for job...
Received job: H:ip-10-114-41-34:33
Workload: Hello! (6)
Sending status: 0/6 complete
Sending status: 1/6 complete
Sending status: 2/6 complete
Sending status: 3/6 complete
Sending status: 4/6 complete
Sending status: 5/6 complete
Result: !olleH

The reverse_client script hangs after "Sending job" until a second instance of 
the reverse_worker script runs. Sometimes even the second instance will not send 
the result back to the client and a third run is necessary. A successful run of 
the worker causes the client script to print its last line of output.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-02-02 07:07 UTC] hradtke@php.net
I can recreate this bug with the following script:
<?php
$gmworker= new GearmanWorker();

$gmworker->addServer();

$gmworker->addFunction("reverse", function ($job) {
  return 'some example result';
});

$gmworker->work();

It looks like the script may terminate before the result has a chance to reach 
the gearmand server. What is the reason for not running the the worker in a 
while loop?
 [2012-02-02 07:07 UTC] hradtke@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: hradtke
 [2012-02-02 17:09 UTC] jon dot tai at gmail dot com
In my use case, the work done by the worker may cause its configuration (or even code, via 
plugins) to change. To ensure that it starts each job with a completely clean and fresh state, I 
have it exit after the job is done. It is then automatically started again with supervisord. 
Performance is not a concern because throughput is very low -- a few jobs per hour max.
 [2012-08-06 04:53 UTC] hradtke@php.net
If performance is not a concern, would adding a sleep(1) call to the end of the 
script fix the problem? This would allow the data to be sent back.
 [2012-08-13 17:37 UTC] jon dot tai at gmail dot com
That's exactly what we do now -- call sleep(1) at the end of the script.
 [2012-08-15 15:18 UTC] hradtke@php.net
-Status: Feedback +Status: Closed
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Jul 05 18:01:20 2020 UTC