gearman

Multiple Gearman workers receive same job


I have two workers running at the same time, currently they both receive the same job at the exact same time. I was under the impression that while Worker A was running a job, Worker B would receive the next job in the queue. Each job takes about 10 seconds to complete. How do I accomplish this?

I've simplified my code to this: (let's say client gets called twice two seconds apart)

CLIENT

$client = new GearmanClient();
$client->addServer();

$client->doBackground("my_task");

WORKER

$worker = new GearmanWorker();
$worker->addServer();
$worker->addFunction("my_task", "my_task_fn");

while($worker->work());

function my_task_fn($job) {
    echo $job->handle(); // both workers show same job #, I want each worker getting a different job
    sleep(10);
}

Solution

  • What you're describing shouldn't be happening, i have included an example for you to get of the ground. The client script wont complete until the worker response with the response. But you can adapt easy enough by changing the 'doNormal' to 'doBackground'. Place a sleep counter in your worker function to slow the worker down, and put your client in a loop to create a lot of jobs to see the process working easer.

    Client Code

    // Create our client object
    $client = new GearmanClient();
    
    // Add a server
    $client->addServer(); // by default host/port will be "localhost" & 4730
    
    echo "Sending job\n";
    
    // Send reverse job
    $result = $client->doNormal("reverse", "Hello!");
    if ($result) {
        echo "Success: $result\n";
    }
    

    Worker Code

    // Create our worker object
    $worker = new GearmanWorker();
    
    // Add a server (again, same defaults apply as a worker)
    $worker->addServer();
    
    // Inform the server that this worker can process "reverse" function calls
    $worker->addFunction("reverse", "reverse_fn");
    
    while (1) {
        print "Waiting for job...\n";
        $ret = $worker->work(); // work() will block execution until a job is delivered
        if ($worker->returnCode() != GEARMAN_SUCCESS) {
            break;
        }
    }
    
    // A much simple reverse function
    function reverse_fn(GearmanJob $job) {
        $workload = $job->workload();
        echo "Received job: " . $job->handle() . "\n";
        echo "Workload: $workload\n";
        $result = strrev($workload);
        echo "Result: $result\n";
        return $result;
    }