Skip to content

Commit

Permalink
basic loadbalancer
Browse files Browse the repository at this point in the history
  • Loading branch information
fcuny committed Mar 23, 2010
1 parent 00fc3df commit 8a63bc8
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 0 deletions.
87 changes: 87 additions & 0 deletions lib/Plack/Middleware/Proxy/LoadBalancer.pm
@@ -0,0 +1,87 @@
package Plack::Middleware::Proxy::LoadBalancer;
use strict;
use warnings;
use parent 'Plack::Middleware';

use Plack::Util::Accessor qw/backends/;

our $VERSION = '0.01';

sub select_backend {
my $self = shift;

if ( ref $self->backends eq 'ARRAY' ) {
return $self->backends->[ int( rand( @{ $self->backends } ) ) ];
}
elsif ( ref $self->backends eq 'HASH' ) {
return (
sort { $b->{value} <=> $a->{value} }
map { { value => rand() * $self->backends->{$_}, host => $_ }; }
keys %{ $self->backends }
)[0]->{host};
}
else {
return $self->backends;
}
}

sub call {
my ( $self, $env ) = @_;
my $url = $self->select_backend();
$env->{'plack.proxy.remote'} = $self->select_backend;
$self->app->($env);
}

1;

__END__
=head1 NAME
Plack::Middleware::Proxy::LoadBalancer - Simple load balancer
=head1 SYNOPSIS
use Plack::Builder;
use Plack::App::Proxy;
builder {
enable "Proxy::LoadBalancer", backends => ['10.0.0.1:8080', '10.0.0.1:8081'];
Plack::App::Proxy->new()->to_app;
};
=head1 DESCRIPTION
Plack::Middleware::Proxy::LoadBalancer allow you to define several backends.
=head1 OPTIONS
=over 4
=item backends
enable "Proxy::LoadBalancer", backends => '10.0.0.1:8080';
Or
enable "Proxy::LoadBalancer", backends => ['10.0.0.1:8080', '10.0.0.1:8081'];
Or
enable "Proxy::LoadBalancer", backends => {'10.0.0.1:8080' => 0.4, '10.0.0.1:8081' => 0.5, '10.0.0.1:8002' => 0.3};
More than one backend can be defined. Weight can be given to backends.
=back
=head1 AUTHOR
Franck Cuny
=head1 SEE ALSO
L<Plack::App::Proxy>
=cut
31 changes: 31 additions & 0 deletions t/middleware/loadbalancer.t
@@ -0,0 +1,31 @@
use strict;
use warnings;
use Plack::App::Proxy;
use Plack::Middleware::Proxy::LoadBalancer;
use Test::More;
use Plack::App::Proxy::Test;

test_proxy(
proxy => sub {
Plack::Middleware::Proxy::LoadBalancer->wrap(
Plack::App::Proxy->new(),
backends => ["http://$_[0]:$_[1]/"]),
},
app => sub {
my $env = shift;
use YAML::Syck;
warn Dump $env;
[ 200, [ Via => '1.0 lucy' ], [ 'Hello' ] ];
},
client => sub {
my $cb = shift;
my $req = HTTP::Request->new( GET => "http://localhost/" );
my $res = $cb->($req);
ok $res;
#like $res->header( 'Via' ), qr/1\.0 lucy\s*,\s*\b1\.[01] /;
#like $res->header( 'Via' ), qr(${\ quotemeta $req->uri->host});
#like $res->header( 'Via' ), qr(${\ quotemeta $req->uri->port});
},
);

done_testing;

0 comments on commit 8a63bc8

Please sign in to comment.