Hi all,

this may be a little off-topic but I thought I post it anyway...

In my use of Apache/mod_perl as an app. server, I needed a way to control maximum concurrency for a given task. An example: I have a handler that runs a task on behalf of a given customer out of a (limited) set of customers. I don't want to hog all my Apache children for one customer by going up to MaxClient children and deny all other requests so all other customers are out of luck.

Something like mod_throttle isn't an option as I don't want to simply discard requests as they come in, I still have to process them but at a later time.

As Perrin indicated several times, the data-sharing between Apache children is easily solved using for instance MLDBM::Sync or IPC::MM.

So I whipped up a class which uses IPC::MM to maintain a shared hash, each key is a given id (in the above example that would be a unique customer id) and in the value, I keep a counter.

Example code:

sub handler
{
my $request = shift;

...

my $id;

# parse request etc., sets $id based on something in the request (url param/http header/whatever)

# get scoreboard (singleton, constructed in parent, shared by children), this is an object that maintains the shared cache

my $scoreBoard = TTGP::Edge::Server::ScoreBoard->instance();

my ($yesCanDo, $concurrencyLevel) = $scoreBoard->canDo($id);

if ($yesCanDo) {
# process the request, currently $concurrencyLevel requests running for this id
} else {
# Oops, we reached the maximum
# Drop request in some (persistent) queue where a daemon (or cron job) picks it up later
}

...

# and tell $scoreBoard we're done with this $id

$scoreBoard->done($id);
}

Quite cool: I can send a stream of requests for a given id to my handler and still have enough children available for other work.

I hope I can generalize this and send it off to CPAN.

My Apache/mod_perl-based app server went up another step in usefullness today!

Regards,

Bas.


Reply via email to