Release 0.06
[MogileFS-Network.git] / lib / MogileFS / Network.pm
blobec940896d61dcd754819a47167f58bed3cd3bfe4
1 package MogileFS::Network;
3 =head1 NAME
5 MogileFS::Network - Network awareness and extensions for MogileFS::Server
7 =head1 DESCRIPTION
9 This collection of modules adds multiple network awareness to the MogileFS
10 server. It provides two replication policies, 'MultipleNetworks' and
11 'HostsPerNetwork'; and also provides a plugin 'ZoneLocal' that causes
12 get_paths queries to be returned in a prioritized order based on locality of
13 storage.
15 For information on configuring a location-aware installation of MogileFS
16 please check out the MogileFS wiki.
18 L<http://code.google.com/p/mogilefs/wiki/ConfigureMultiNet>
20 =cut
22 use strict;
23 use warnings;
25 use Net::Netmask;
26 use Net::Patricia;
27 use MogileFS::Config;
29 our $VERSION = "0.06";
31 use constant DEFAULT_RELOAD_INTERVAL => 60;
33 my $trie = Net::Patricia->new(); # Net::Patricia object used for cache and lookup.
34 my $next_reload = 0; # Epoch time at or after which the trie expires and must be regenerated.
35 my $has_cached = MogileFS::Config->can('server_setting_cached');
37 sub zone_for_ip {
38 my $class = shift;
39 my $ip = shift;
41 return unless $ip;
43 check_cache();
45 return $trie->match_string($ip);
48 sub check_cache {
49 # Reload the trie if it's expired
50 return unless (time() >= $next_reload);
52 $trie = Net::Patricia->new();
54 my @zones = split(/\s*,\s*/, get_setting("network_zones"));
56 my @netmasks; # [ $bits, $netmask, $zone ], ...
58 foreach my $zone (@zones) {
59 my $zone_masks = get_setting("zone_$zone");
61 if (not $zone_masks) {
62 warn "couldn't find network_zone <<zone_$zone>> check your server settings";
63 next;
66 foreach my $network_string (split /[,\s]+/, $zone_masks) {
67 my $netmask = Net::Netmask->new2($network_string);
69 if (Net::Netmask::errstr()) {
70 warn "couldn't parse <$zone> as a netmask. error was <" . Net::Netmask::errstr().
71 ">. check your server settings";
72 next;
75 push @netmasks, [$netmask->bits, $netmask, $zone];
79 # Sort these by mask bit count, because Net::Patricia doesn't say in its docs whether add order
80 # or bit length is the overriding factor.
81 foreach my $set (sort { $a->[0] <=> $b->[0] } @netmasks) {
82 my ($bits, $netmask, $zone) = @$set;
84 if (my $other_zone = $trie->match_exact_string("$netmask")) {
85 warn "duplicate netmask <$netmask> in network zones '$zone' and '$other_zone'. check your server settings";
88 $trie->add_string("$netmask", $zone);
91 my $interval = get_setting("network_reload_interval") || DEFAULT_RELOAD_INTERVAL;
93 $next_reload = time() + $interval;
95 return 1;
98 # This is a separate subroutine so I can redefine it at test time.
99 sub get_setting {
100 my $key = shift;
101 if ($has_cached) {
102 my $val = MogileFS::Config->server_setting_cached($key);
103 return $val;
105 # Fall through to the server in case we don't have a cached value yet.
106 return MogileFS::Config->server_setting($key);
109 sub test_config {
110 my $class = shift;
112 my %config = @_;
114 no warnings 'redefine';
116 *get_setting = sub {
117 my $key = shift;
118 return $config{$key};
121 $next_reload = 0;
124 =head1 COPYRIGHT
126 Copyright 2011 - Jonathan Steinert
128 =head1 AUTHOR
130 Jonathan Steinert
132 =head1 LICENSE
134 This module is licensed under the same terms as Perl itself.
136 =cut