Using gearman, that's how.

http://www.danga.com/gearman/

Example plugin:

#!/usr/bin/perl -w

use Gearman::Client::Async;
use Storable qw(thaw);

sub register {
    my ($self, $qp, @args) = @_;
    my @gearmen = $qp->config('gearmand_hosts');
    if ([EMAIL PROTECTED]) {
        $gearmen[0] = 'localhost';
    }
    $self->{client} = Gearman::Client::Async->new(
        job_servers => [EMAIL PROTECTED],
    );

    $self->{timeout}     = $qp->config('gearman.timeout') || 5;
    $self->{retry_count} = $qp->config('gearman.retry_count') || 0;

    $self->register_hook("data_post", "check_spam");
    $self->register_hook("data_post", "check_spam_done");
}

sub check_spam {
    my ($self, $transaction) = @_;

    $self->log(LOGDEBUG, "check_spam");

    my $qp = $self->qp;

    my $mail = $transaction->header->as_string .
               $transaction->body_as_string;

    my $task = Gearman::Task->new("scan", \$mail, {
            on_complete => sub {
                my $output = shift();
                if (!$output) {
$qp->log(LOGALERT, "Nothing returned from Gearman");
                    $qp->finish_continuation;
                    return;
                }
                $output = thaw($$output);
                # do something with $output here

                $qp->finish_continuation;
            },
            on_fail => sub {
                $qp->log(LOGALERT, "Gearman failed");
                $qp->finish_continuation;
            },
            on_retry => sub {
$qp->log(LOGALERT, "Gearman failed but retrying for $_[0] time");
            },
            timeout     => $self->{timeout},
            retry_count => $self->{retry_count},
    });
    $self->{client}->add_task($task);
    return CONTINUATION;
}

And the worker just returns freeze($struct) and it all "just works".

The advantage of this is you can add in extra workers if you get too many timeouts, and gearman smoothes over any lumpiness in connections for you.

(I think this is a bit like what MailChannels are doing but using mod_perl instead of gearman).

Matt.

Reply via email to