Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

basic loadbalancer

  • Loading branch information...
commit 8a63bc8dc33cd31987cbaedd140c06e03fe5d3fc 1 parent 00fc3df
@franckcuny franckcuny authored
View
87 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
+
+
View
31 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;
Please sign in to comment.
Something went wrong with that request. Please try again.