Building a distributed app with PHP and Net_Gearman, part 2

Let’s continue our exploration of the Net_Gearman API by extending the Net_Gearman client/server application we built earlier.

First, if you haven’t already, download the source for the examples in this tutorial

2. Task Sets

In our original example, we use the magic Example() call in the client to queue up our job with the gearman server.  This is convenient for a quick and dirty job submission, but there’s a more sophisticated way to do it.  You can create an explicit Net_Gearman_Task object, put it into a Net_Gearman_Set object, and run the task set.  (Most of the online documentation I’ve seen for Net_Gearman uses this technique, but I wanted to introduce the super-simple magic function call method first.)

Here is the relevant part of gm_client2.php:

What was once a single line of code is now four lines of code.  That seems somewhat inconvenient, but doing things this way has a number of advantages:

  • you can set priorities on your tasks (normal, background, or high priority)
  • you could run a number of tasks with one call to runSet()
  • you can add callbacks to your tasks so that you can get return values from the jobs

To set priorities on a task, do the following:

Valid values for the type are

  • Net_Gearman_Task::JOB_BACKGROUND
  • Net_Gearman_Task::JOB_NORMAL  (this is the default)
  • Net_Gearman_Task::JOB_HIGH

This is a bit of a deviation from the underlying Gearman API, which supports LOW, NORMAL, and HIGH for priority, and you can run any task as a background task.  You’ll need to dig into the Gearman docs if you want to take advantage of this mechanism; my examples don’t make use of this.

It should be fairly obvious how you add multiple tasks to a task set.

As for the third advantage, callbacks, we’ll dig into that stuff next.

3. Task Callbacks

Your client software will probably want to know when the job is finished, and whether the job succeeded.   You can use a task callback to get this information.  We modify the client script to add a callback to the task before we run the task set.  Here is the relevant part of gm_client3.php:

This callback function is triggered when the task is completed.  If you run gm_worker3.php and gm_client3.php, you’ll see output like this:

The callback receives these parameters:

  • $func – a string representing the job class that was called (in this case, “Example1”)
  • $handle – an identifier for the job within the gearman server (in this case, “H:localhost:399”)
  • $result – an array with the result of the job class’s run() function; note that if the run() function does not return an array, the value that it does return will be put into a hashed array under the key ‘result’

One other interesting thing to note: you can attach multiple callback functions to a task; Net_Gearman will call each in turn upon completion of the task.  You can even attach the same function more than once if you are so inclined.

4. Return Values

Let’s look at how we would pass useful information back from the worker to the client.  You might need more than a simple boolean success/failure value.

First, lets use a different job class; our new one will capture the output of the command that it runs and it will send this output back along with a success/failure result value.  Here is Example2.php:

The key is to return your values in an array, and this array will be passed directly to your complete callback.

We modify our worker script to use Example2.  Here is the relevant portion of gm_worker4.php:

We modify the client script to use Example2, and to display the entire result array.  Here are the relevant portions of gm_client4.php:

If you run gm_worker4.php and gm_client4.php, you’ll see output like this:

Notice that we got the result unmodified.  If the run() function returns anything other than an array, Net_Gearman will put that value (boolean, string, object, etc.) into a hashed array under the ‘result’ key.

In our next installment, we’ll look at error handling and callbacks in the worker.

Part 1 · Part 3  · Part 4

Leave a comment

Your email address will not be published. Required fields are marked *