1 package MogileFS
::Host
;
4 use MogileFS
::Util
qw(throw);
7 use MogileFS
::Connection
::Mogstored
;
8 use MogileFS
::Connection
::HTTP
;
9 use MogileFS
::ConnectionPool
;
14 MogileFS::Host - host class
18 # Centralized here instead of three places.
19 my @observed_fields = qw
/observed_state/;
20 my @fields = (qw
/hostid hostname hostip status http_port http_get_port altip altmask/,
23 # TODO: Validate a few things: state, observed state.
25 my ($class, $args, $dev_factory) = @_;
27 dev_factory
=> $dev_factory,
31 $self->{mask
} = ($self->{altip
} && $self->{altmask
}) ?
32 Net
::Netmask
->new2($self->{altmask
}) : undef;
38 my ($class, $state) = @_;
39 return $state && $state =~ /\A(?:alive|dead|down)\z/;
44 sub id
{ $_[0]{hostid
} }
45 sub name
{ $_[0]{hostname
} }
46 sub hostname
{ $_[0]{hostname
} }
47 sub hostip
{ $_[0]{hostip
} }
48 sub status
{ $_[0]{status
} }
49 sub http_port
{ $_[0]{http_port
} }
52 return $_[0]->{http_get_port
} || $_[0]->{http_port
};
57 if ($self->{mask
} && $self->{altip
} &&
58 ($MogileFS::REQ_altzone
|| ($MogileFS::REQ_client_ip
&&
59 $self->{mask
}->match($MogileFS::REQ_client_ip
)))) {
60 return $self->{altip
};
62 return $self->{hostip
};
68 my @tofetch = @_ ?
@_ : @fields;
69 return { map { $_ => $self->{$_} } @tofetch };
73 return $_[0]->fields(@observed_fields);
77 return $_[0]->status eq 'alive';
80 sub observed_reachable
{
82 return $self->{observed_state
} && $self->{observed_state
} eq 'reachable';
85 sub observed_unreachable
{
87 return $self->{observed_state
} && $self->{observed_state
} eq 'unreachable';
90 # returns/creates a MogileFS::Connection::Mogstored object to the
91 # host's mogstored management/side-channel port (which starts
92 # unconnected, and only connects when you ask it to, with its sock
96 return $self->{mogstored_conn
} ||=
97 MogileFS
::Connection
::Mogstored
->new($self->ip, $self->sidechannel_port);
100 sub sidechannel_port
{
101 # TODO: let this be configurable per-host? currently it's configured
102 # once for all machines.
103 MogileFS
->config("mogstored_stream_port");
106 # starts an HTTP request on the given $port with $method to $path
107 # Calls cb with an HTTP::Response object when done
109 my ($self, $port, $method, $path, $opts, $cb) = @_;
112 $http_pool->start($opts->{ip
} || $self->ip, $port, sub {
113 $_[0]->start($method, $path, $opts, $cb);
117 # Returns a ready, blocking HTTP connection
118 # This is only used by replicate
120 my ($self, $opts) = @_;
121 my $ip = $opts->{ip
} || $self->ip;
122 my $port = $opts->{port
} || $self->http_port;
125 my $conn = $http_pool->conn_get($ip, $port);
126 $conn->sock->blocking(1);
130 # Returns a blocking HTTP connection back to the pool.
131 # This is the inverse of http_conn_get, and should be called when
132 # done using a connection (iff the connection is really still alive)
133 # (and makes it non-blocking for future use)
134 # This is only used by replicate.
136 my ($self, $conn) = @_;
137 $conn->sock->blocking(0);
138 $http_pool->conn_put($conn);
142 my ($self, $method, $path, $opts, $cb) = @_;
144 $self->_http_conn($self->http_get_port, $method, $path, $opts, $cb);
148 my ($self, $method, $path, $opts, $cb) = @_;
150 my $port = delete $opts->{port
} || $self->http_port;
151 $self->_http_conn($port, $method, $path, $opts, $cb);
154 # FIXME - make these customizable
156 return if $http_pool;
158 $http_pool = MogileFS
::ConnectionPool
->new("MogileFS::Connection::HTTP");