Wednesday, December 28, 2011

Tasksets in Gearman

Here's a little tidbit about using the Gearman Perl Client:

Gearman is a powerful yet simple job queuing and distribution framework with clients in a variety of languages,  written by the Djanga folks (who also wrote memcached).

For a recent project, I needed to be able to queue up a potentially large number of jobs during one phase of execution, and begin processing them  went out to find more work to queue. At some point, we would know that we had no more jobs to add to the queue, and would be ready to move on to the next stage when all the jobs had completed. Gearman::Client provides a synchronous "do_task()" method that waits for a task to return its result, and a "dispatch_background()" method that runs jobs in the background. The limitation of background jobs is that it does not return results: you are merely able to monitor the status of the job to see when it completes. Task sets to the rescue!

Task sets allow you to group a number of jobs together, begin executing them immediately in the background, but with full access to the return values, errors and retries via event handlers. Furthermore, task sets provide a wait() method that will wait until all jobs have finished (either succeeded or failed), which was exactly what we needed.

Here's some sample client code that I used to verify this functionality:

1:  #!/usr/bin/env perl  
2:  use strict;  
3:  use warnings;  
4:  use Gearman::Client;  
5:  my $client = Gearman::Client->new();  
6:  $client->job_servers("localhost:4730");  
7:  my $tasks = $client->new_task_set();  
8:  for my $count ( 1 .. 10 ) {  
9:    $tasks->add_task(  
10:      echo => $count,  
11:      {  
12:        on_complete =>  
13:         sub { my $result = shift; warn "from job $count got " . $$result; },  
14:        on_fail => sub { warn "ERROR from job $count"; }  
15:      }  
16:    );  
17:  }  
18:  warn "done adding tasks";  
19:  sleep 5;  
20:  warn "waiting";  
21:  $tasks->wait;  
22:  warn "bye";  

The critical part of this prototype was to verify that jobs began to be processed by workers when the job was added to the taskset on line 9, and not only at the call to wait() on line 21. 

And here is the trivial echo worker that returns whatever you send to it:

1:  #!/usr/bin/env perl  
2:  use strict;  
3:  use warnings;  
4:  use Gearman::Worker;  
5:  sub echo_worker {  
6:    my $job = shift;  
7:    my $arg = $job->arg;  
8:    warn "ARG: $arg";  
9:    return $arg ;  
10:  }  
11:  my $w = Gearman::Worker->new();  
12:  $w->job_servers( "localhost:4730" );  
13:  $w->register_function( echo => \&echo_worker );  
14:  $w->work while 1;  

Without tasksets, it would have been substantially trickier to 

Tuesday, December 27, 2011

Review: Switch: How to Change Things When Change Is Hard

I recently completed the audiobook version of  Switch: How to Change Things When Change Is Hard by Chip Heath and Dan Heath. In this excellent book, they break down change factors into three components: the logical mind, the emotional mind, and the environment. Borrowing a metaphor from another excellent book, The Happiness Hypothesis, they characterize human decision making as a rider perched atop an elephant. Although the rider (the logical mind) has the power of foresight, thinking and planning for the future, he can only exercise limited control over the greater strength of the emotional mind, the elephant. When emotions take over and runs wild, the tiny rider has only limited control and must hang on for the ride. The rider thinks about tomorrow, skipping the cake today for a healthier body next summer. However, without the elephant, the rider has difficulty making decisions and taking action. They summarize their recipe for change as follows:

1. Direct the rider. Often what appears to be inaction or resistance is simply confusion. Script the critical change steps into simple, crystal-clear actions that can be easily followed. Look for early, or previous successes (bright spots), and identify the key components to change. Often large, complex problems seem to demand complex solutions, but by looking for common elements in the bright spots, we can make progress through simple steps. For example, a weightloss campaign that targets whole milk as the largest single source of fat simply suggested buying skim/1% milk and was effective. Solutions-based therapy is another example of the "bright spot" technique. When in your relationship/career/life were you happy.

2. Motivate the elephant. What looks like laziness is often exhaustion. People have a limited amount of self control, and expending this control fighting their elephant decreases their capacity for other efforts. Make an emotional appeal that is directed at making people feel something. Aligning logic and emotion is critical. Knowledge does not bring about change, only emotion and desire change behavior. Powerpoint displays rarely get peoples' blood boiling, so find more visceral ways to get your point across. In one example, as part of a campaign to reform corporate purchasing, a glove shrine with more than 400 gloves, many identical except for their prices, was piled on a fancy executive's table to demonstrate the insanity of each business unit independently negotiating  and purchasing its own supplies. Always think, "what is the feeling here".

3. Shape the path. What looks like a people problem is often a situation problem. A good leader doesn't ask "what's wrong with these people, they just aren't getting it". Rather, consider what factors in the environment can be changed to influence the outcome. As an example, they described an experiment in which people at a movie theater were given large or extra large buckets of badly tasting popcorn. Repeated experiments confirmed that people given the extra large buckets ate more. Changing the bucket size changed behavior.

Other ideas:

Rally the herd: Use peer pressure to drive conformity. If the majority of people are already doing the desired behavior, publicize it and encourage people to do the right thing. For example, publicize that 70% of employees get their expense in on time, or 90% of reviewers complete their review within X amount of time. As a corollary, don't publicize statistics that reinforce undesired behavior, e.g. only 30% of employees submit their expense reports on time.

Make use of action triggers. Encourage behavior by tying it to a specific time and place or event. For example, ask employees returning from a conference to "write up some notes for the team when the fasten seatbelts sign goes off on the flight home". Students asked to write a paper over break did better when they specified when and where they would write it.

Use checklists. The "lowly checklist" is extremely effective at making sure that procedures are followed, or ideas are primed. For example, the "cisco pre-acquisition checklist" was a useful tool for ensuring that basic questions were asked prior to acquisition.

I highly recommend Switch: How to Change Things When Change Is Hard for anyone attempting to create change at the personal, organizational or even societal level.