File Coverage

blib/lib/Perlbal/Plugin/Highpri.pm
Criterion Covered Total %
statement 6 55 10.9
branch 0 18 0.0
condition 0 18 0.0
subroutine 2 9 22.2
pod 0 4 0.0
total 8 104 7.6


line stmt bran cond sub pod time code
1             ###########################################################################
2             # plugin that makes some requests high priority. this is very LiveJournal
3             # specific, as this makes requests to the client protocol be treated as
4             # high priority requests.
5             ###########################################################################
6              
7             package Perlbal::Plugin::Highpri;
8              
9 1     1   1807 use strict;
  1         2  
  1         40  
10 1     1   7 use warnings;
  1         1  
  1         941  
11              
12             # keep track of services we're loaded for
13             our %Services;
14              
15             # called when we're being added to a service
16             sub register {
17 0     0 0   my ($class, $svc) = @_;
18              
19             # create a compiled regexp for very frequent use later
20 0           my $uri_check = qr{^(?:/interface/(?:xmlrpc|flat)|/login\.bml)$};
21 0           my $host_check = undef;
22              
23             # setup default extra config info
24 0           $svc->{extra_config}->{highpri_uri_check_str} = '^(?:/interface/(?:xmlrpc|flat)|/login\.bml)$';
25 0           $svc->{extra_config}->{highpri_host_check_str} = 'undef';
26              
27             # config setter reference
28             my $config_set = sub {
29 0     0     my ($out, $what, $val) = @_;
30 0 0 0       return 0 unless $what && $val;
31              
32             # setup an error sub
33             my $err = sub {
34 0 0         $out->("ERROR: $_[0]") if $out;
35 0           return 0;
36 0           };
37              
38             # if they said undef, that's not a regexp, that means use none
39 0           my $temp;
40 0 0 0       unless ($val eq 'undef' || $val eq 'none' || $val eq 'null') {
      0        
41             # verify this regexp works? do it in an eval because qr will die
42             # if we give it something invalid
43 0           eval {
44 0           $temp = qr{$val};
45             };
46 0 0 0       return $err->("Invalid regular expression") if $@ || !$temp;
47             }
48              
49             # see what they want to set and set it
50 0 0         if ($what =~ /^uri_pattern/i) {
    0          
51 0           $uri_check = $temp;
52 0           $svc->{extra_config}->{highpri_uri_check_str} = $val;
53             } elsif ($what =~ /^host_pattern/i) {
54 0           $host_check = $temp;
55 0           $svc->{extra_config}->{highpri_host_check_str} = $val;
56             } else {
57 0           return $err->("Plugin understands: uri_pattern, host_pattern");
58             }
59              
60             # 1 for success!
61 0           return 1;
62 0           };
63              
64             # register things to take in configuration regular expressions
65 0           $svc->register_setter('Highpri', 'uri_pattern', $config_set);
66 0           $svc->register_setter('Highpri', 'host_pattern', $config_set);
67              
68             # more complicated statistics
69             $svc->register_hook('Highpri', 'make_high_priority', sub {
70 0     0     my Perlbal::ClientProxy $cp = shift;
71              
72             # check it against our compiled regexp
73 0 0 0       return 1 if $uri_check &&
74             $cp->{req_headers}->request_uri =~ /$uri_check/;
75 0 0         if ($host_check) {
76 0           my $hostname = $cp->{req_headers}->header('Host');
77 0 0 0       return 1 if $hostname && $hostname =~ /$host_check/;
78             }
79              
80             # doesn't fit, so return 0
81 0           return 0;
82 0           });
83              
84             # mark this service as being active in this plugin
85 0           $Services{"$svc"} = $svc;
86              
87 0           return 1;
88             }
89              
90             # called when we're no longer active on a service
91             sub unregister {
92 0     0 0   my ($class, $svc) = @_;
93              
94             # clean up time
95 0           $svc->unregister_hooks('Highpri');
96 0           $svc->unregister_setters('Highpri');
97 0           return 1;
98             }
99              
100             # load global commands for querying this plugin on what's up
101             sub load {
102             # setup a command to see what the patterns are
103             Perlbal::register_global_hook('manage_command.patterns', sub {
104 0     0     my @res = ("High priority pattern buffer:");
105              
106 0           foreach my $svc (values %Services) {
107 0           push @res, "SET $svc->{name}.highpri.uri_pattern = $svc->{extra_config}->{highpri_uri_check_str}";
108 0           push @res, "SET $svc->{name}.highpri.host_pattern = $svc->{extra_config}->{highpri_host_check_str}";
109             }
110              
111 0           push @res, ".";
112 0           return \@res;
113 0     0 0   });
114              
115 0           return 1;
116             }
117              
118             # unload our global commands, clear our service object
119             sub unload {
120 0     0 0   Perlbal::unregister_global_hook('manage_command.patterns');
121 0           %Services = ();
122 0           return 1;
123             }
124              
125             1;