James Stanley

How to peek all of the jobs in a Beanstalk tube

Wed 30 March 2016

This problem came up at work today. There was a Beanstalk tube with a few hundred jobs in it, getting processed slowly. A particular input didn't seem to be getting processed, and I wanted to know if it existed in the tube and simply hadn't come out yet, or was missing entirely.

Googling the problem was not fruitful. A StackOverflow post from 2011 was answered with "BeanstalkD is a queue - not an array, and not designed to allow access to every item within it". Which is true, but not at all useful when trying to debug a problem like this.

My solution was a Perl script to reserve all jobs in the tube, dump them as JSON, and then exit. Beanstalk implicitly releases a job if the worker that has reserved it disconnects, so this means the program gets hold of every ready job, and then they all return to the ready queue when it exits.

#!/usr/bin/perl
    
use strict;
use warnings;
    
use Beanstalk::Client;
use JSON qw(encode_json);
    
my $q = Beanstalk::Client->new({ server => 'beanstalk-server.example.com' });
$q->watch_only('my_tube');
    
while (my $job = $q->reserve(1)) {
        print encode_json($job->args), "\n";
}

The output is essentially in JSON Lines format.

Obviously, this is not applicable in all circumstances:

  1. if there are millions of large jobs, the program will run out of memory
  2. jobs will get processed by other workers out-of-order because this program reserves and holds jobs from the front of the queue first
  3. if there is never a second in which a job is not added, this program will never exit because it will never know when the queue is empty

But it was useful for me, and it might be useful for you too.

If you like my blog, please consider subscribing to the RSS feed or the mailing list:
or follow me on Twitter.

James Stanley - james@incoherency.co.uk | jesblogfnk2boep4.onion | /ipns/jes.xxx/ | [rss]