Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

basic loadbalancer

  • Loading branch information...
commit 8a63bc8dc33cd31987cbaedd140c06e03fe5d3fc 1 parent 00fc3df
Franck Cuny authored March 23, 2010
87  lib/Plack/Middleware/Proxy/LoadBalancer.pm
... ...
@@ -0,0 +1,87 @@
  1
+package Plack::Middleware::Proxy::LoadBalancer;
  2
+use strict;
  3
+use warnings;
  4
+use parent 'Plack::Middleware';
  5
+
  6
+use Plack::Util::Accessor qw/backends/;
  7
+
  8
+our $VERSION = '0.01';
  9
+
  10
+sub select_backend {
  11
+    my $self = shift;
  12
+
  13
+    if ( ref $self->backends eq 'ARRAY' ) {
  14
+        return $self->backends->[ int( rand( @{ $self->backends } ) ) ];
  15
+    }
  16
+    elsif ( ref $self->backends eq 'HASH' ) {
  17
+        return (
  18
+            sort { $b->{value} <=> $a->{value} }
  19
+                map { { value => rand() * $self->backends->{$_}, host => $_ }; }
  20
+                keys %{ $self->backends }
  21
+        )[0]->{host};
  22
+    }
  23
+    else {
  24
+        return $self->backends;
  25
+    }
  26
+}
  27
+
  28
+sub call {
  29
+    my ( $self, $env ) = @_;
  30
+    my $url = $self->select_backend();
  31
+    $env->{'plack.proxy.remote'} = $self->select_backend;
  32
+    $self->app->($env);
  33
+}
  34
+
  35
+1;
  36
+
  37
+__END__
  38
+
  39
+=head1 NAME
  40
+
  41
+Plack::Middleware::Proxy::LoadBalancer - Simple load balancer
  42
+
  43
+=head1 SYNOPSIS
  44
+
  45
+  use Plack::Builder;
  46
+  use Plack::App::Proxy;
  47
+
  48
+  builder {
  49
+    enable "Proxy::LoadBalancer", backends => ['10.0.0.1:8080', '10.0.0.1:8081'];
  50
+    Plack::App::Proxy->new()->to_app;
  51
+  };
  52
+
  53
+=head1 DESCRIPTION
  54
+
  55
+Plack::Middleware::Proxy::LoadBalancer allow you to define several backends.
  56
+
  57
+=head1 OPTIONS
  58
+
  59
+=over 4
  60
+
  61
+=item backends
  62
+
  63
+  enable "Proxy::LoadBalancer", backends => '10.0.0.1:8080';
  64
+
  65
+Or
  66
+
  67
+  enable "Proxy::LoadBalancer", backends => ['10.0.0.1:8080', '10.0.0.1:8081'];
  68
+
  69
+Or
  70
+
  71
+  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};
  72
+
  73
+More than one backend can be defined. Weight can be given to backends.
  74
+
  75
+=back
  76
+
  77
+=head1 AUTHOR
  78
+
  79
+Franck Cuny
  80
+
  81
+=head1 SEE ALSO
  82
+
  83
+L<Plack::App::Proxy>
  84
+
  85
+=cut
  86
+
  87
+
31  t/middleware/loadbalancer.t
... ...
@@ -0,0 +1,31 @@
  1
+use strict;
  2
+use warnings;
  3
+use Plack::App::Proxy;
  4
+use Plack::Middleware::Proxy::LoadBalancer;
  5
+use Test::More;
  6
+use Plack::App::Proxy::Test;
  7
+
  8
+test_proxy(
  9
+    proxy => sub {
  10
+        Plack::Middleware::Proxy::LoadBalancer->wrap(
  11
+            Plack::App::Proxy->new(),
  12
+            backends => ["http://$_[0]:$_[1]/"]),
  13
+    },
  14
+    app   => sub {
  15
+        my $env = shift;
  16
+	use YAML::Syck;
  17
+	warn Dump $env;
  18
+        [ 200, [ Via => '1.0 lucy' ], [ 'Hello' ] ];
  19
+    },
  20
+    client => sub {
  21
+        my $cb = shift;
  22
+        my $req = HTTP::Request->new( GET => "http://localhost/" );
  23
+        my $res = $cb->($req);
  24
+	ok $res;
  25
+        #like $res->header( 'Via' ), qr/1\.0 lucy\s*,\s*\b1\.[01] /;
  26
+        #like $res->header( 'Via' ), qr(${\ quotemeta $req->uri->host});
  27
+        #like $res->header( 'Via' ), qr(${\ quotemeta $req->uri->port});
  28
+    },
  29
+);
  30
+
  31
+done_testing;

0 notes on commit 8a63bc8

Please sign in to comment.
Something went wrong with that request. Please try again.