mirror of
https://github.com/MariaDB/server.git
synced 2025-07-08 17:02:21 +03:00
150 lines
2.8 KiB
Perl
150 lines
2.8 KiB
Perl
package NDB::Net::Server;
|
|
|
|
use strict;
|
|
use Carp;
|
|
use Socket;
|
|
|
|
require NDB::Net::Base;
|
|
|
|
use vars qw(@ISA);
|
|
@ISA = qw(NDB::Net::Base);
|
|
|
|
# constructors
|
|
|
|
my $log;
|
|
|
|
sub initmodule {
|
|
$log = NDB::Util::Log->instance;
|
|
}
|
|
|
|
my %servercache = ();
|
|
|
|
NDB::Net::Server->attributes(
|
|
id => sub { s/^\s+|\s+$//g; m/^\S+$/ && ! m!/! },
|
|
domain => sub { $_ == PF_UNIX || $_ == PF_INET },
|
|
);
|
|
|
|
sub desc {
|
|
my $server = shift;
|
|
my $id = $server->getid;
|
|
return "server $id";
|
|
}
|
|
|
|
sub add {
|
|
my $server = shift;
|
|
@_ % 2 == 0 or confess 0+@_;
|
|
my(%attr) = @_;
|
|
if ($servercache{$server->getid}) {
|
|
$log->put("duplicate server")->push($server);
|
|
return undef;
|
|
}
|
|
$servercache{$server->getid} = $server;
|
|
return 1;
|
|
}
|
|
|
|
sub get {
|
|
my $class = shift;
|
|
@_ == 1 or confess 0+@_;
|
|
my($id) = @_;
|
|
$id =~ s/^\s+|\s+$//g;
|
|
my $server = $servercache{$id};
|
|
if (! $server) {
|
|
$log->put("$id: undefined server");
|
|
return undef;
|
|
}
|
|
$log->put("found")->push($server)->debug;
|
|
return $server;
|
|
}
|
|
|
|
sub delete {
|
|
my $server = shift;
|
|
delete $servercache{$server->getid};
|
|
}
|
|
|
|
sub deleteall {
|
|
my $class = shift;
|
|
for my $id (sort keys %servercache) {
|
|
my $server = $servercache{$id};
|
|
$server->delete;
|
|
}
|
|
}
|
|
|
|
# local server is this server process
|
|
|
|
my $localserver;
|
|
|
|
sub setlocal {
|
|
my $server = shift;
|
|
@_ == 0 or confess 0+@_;
|
|
$localserver = $server;
|
|
}
|
|
|
|
sub islocal {
|
|
my $server = shift;
|
|
@_ == 0 or confess 0+@_;
|
|
return $localserver eq $server;
|
|
}
|
|
|
|
# client side
|
|
|
|
sub testconnect {
|
|
my $server = shift;
|
|
@_ == 0 or confess 0+@_;
|
|
my $socket = $server->connect or
|
|
$log->push($server), return undef;
|
|
$socket->close;
|
|
return 1;
|
|
}
|
|
|
|
sub request {
|
|
my $server = shift;
|
|
@_ == 1 or confess 0+@_;
|
|
my($cmd) = @_;
|
|
unless (ref($cmd) && $cmd->isa('NDB::Net::Command')) {
|
|
confess 'oops';
|
|
}
|
|
my $socket = $server->connect
|
|
or $log->push($server), return undef;
|
|
anon: {
|
|
my $line = $cmd->getline;
|
|
my $n = $socket->write("$line\n");
|
|
defined($n) && $n == length("$line\n")
|
|
or $log->push($server), return undef;
|
|
shutdown($socket->{fh}, 1);
|
|
}
|
|
my $value;
|
|
try: {
|
|
my $last;
|
|
loop: {
|
|
my $line = $socket->readline;
|
|
defined($line)
|
|
or $log->push($server), last try;
|
|
if ($socket->getreadend) {
|
|
last loop;
|
|
}
|
|
while (chomp($line)) {}
|
|
$log->put($line)->user
|
|
unless $log->hasvalue($line);
|
|
$last = $line;
|
|
redo loop;
|
|
}
|
|
if (! $log->hasvalue($last)) {
|
|
$log->put("missing return value in \"$last\"")->push($server);
|
|
last try;
|
|
}
|
|
$value = $log->getvalue($last);
|
|
defined($value)
|
|
or $log->push, last try;
|
|
$value = $value->[0];
|
|
if (! defined($value)) {
|
|
$log->put("failed")->push($cmd);
|
|
last try;
|
|
}
|
|
}
|
|
$socket->close;
|
|
return $value;
|
|
}
|
|
|
|
1;
|
|
# vim:set sw=4:
|