root/trunk/lib/Perlbal/Plugin/LazyCDN.pm

Revision 592, 3.0 kB (checked in by hachi, 3 years ago)

Add hooks and handle for the case of missing files for Lazy CDN population.

Line 
1package Perlbal::Plugin::LazyCDN;
2
3use IO::Socket::INET;
4use Perlbal;
5use Perlbal::ClientHTTPBase;
6use strict;
7use warnings;
8
9sub load {
10    # add up custom configuration options that people are allowed to set
11    Perlbal::Service::add_tunable(
12            # allow the following:
13            #    SET myservice.fallback_service = proxy
14            fallback_service => {
15                des => "Service name to fall back to when a static get or concat get requests something newer than on disk.",
16                check_role => "web_server",
17            }
18        );
19
20    Perlbal::Service::add_tunable(
21            # allow the following:
22            #    SET myservice.fallback_udp_ping_addr = 5
23            fallback_udp_ping_addr => {
24                des => "Address and port to send UDP packets containing URL requests .",
25                check_role => "web_server",
26                check_type => ["regexp", qr/^\d+\.\d+\.\d+\.\d+:\d+$/, "Expecting IP:port of form a.b.c.d:port."],
27            }
28        );
29    return 1;
30}
31
32# remove the various things we've hooked into, this is required as a way of
33# being good to the system...
34sub unload {
35    Perlbal::Service::remove_tunable('fallback_service');
36    Perlbal::Service::remove_tunable('fallback_udp_ping_addr');
37    return 1;
38}
39
40# called when we're being added to a service
41sub register {
42    my ($class, $svc) = @_;
43
44    my $socket;
45
46    my $hook = sub {
47        my Perlbal::ClientHTTPBase $client = shift;
48        my $last_modified = shift; # unix timestamp for last modified of the concatenated files
49
50        my $fallback_service_name = $client->{service}->{extra_config}->{fallback_service};
51        return unless $fallback_service_name;
52
53        my $fallback_service = Perlbal->service($fallback_service_name);
54        return unless $fallback_service;
55
56        my $req_hd = $client->{req_headers};
57
58        my $uri = $req_hd->request_uri;
59
60        my ($v) = $uri =~ m/\bv=(\d+)\b/;
61
62        if (defined $last_modified) {
63            return unless $v;
64            return 0 unless $v > $last_modified;
65        }
66
67        if (my $fallback_ping_addr = $client->{service}->{extra_config}->{fallback_udp_ping_addr}) {
68            $socket ||= _ping_socket($fallback_ping_addr);
69            $socket->write($uri);
70        }
71
72        $fallback_service->adopt_base_client( $client );
73
74        return 1;
75    };
76
77    $svc->register_hook('LazyCDN', 'static_get_poststat_pre_send', $hook);
78    $svc->register_hook('LazyCDN', 'concat_get_poststat_pre_send', $hook);
79
80    $svc->register_hook('LazyCDN', 'static_get_poststat_file_missing', $hook);
81    $svc->register_hook('LazyCDN', 'concat_get_poststat_file_missing', $hook);
82
83    return 1;
84}
85
86# called when we're no longer active on a service
87sub unregister {
88    my ($class, $svc) = @_;
89    return 1;
90}
91
92sub _ping_socket {
93    my $hostspec = shift;
94    my $socket = IO::Socket::INET->new(
95            PeerAddr  => $hostspec,
96            Proto     => 'udp',
97            Broadcast => 1,
98            ReuseAddr => 1)
99        or warn "Can't bind udp ping socket: $!\n";
100    return $socket;
101}
102
1031;
Note: See TracBrowser for help on using the browser.