Apache thrift: проблемы с таймаутом клиента
у меня есть некоторая бережливость Apache (V. 0.6.1) тестовое приложение с perl-сервером и php-клиентом.
поведение, которое я не могу объяснить: если мы вызываем server-method с недопустимым аргументом, мы видим ошибку в server-output, но php-клиент остается ждать ответа бесконечно.
вот источники сервера:
sub new {
my $classname = shift;
my $self = {};
return bless($self,$classname);
}
sub DateToTimestamp
{
my ($self, $date) = @_;
my $result = CommonAPI::DateToTimestamp($date);
return $result;
}
eval {
my $handler = new RPCHandler;
my $processor = new RPCPerformanceTest::RPCPerformanceTestProcessor($handler);
my $serversocket = new Thrift::ServerSocket(9091);
my $forkingserver = new Thrift::ForkingServer($processor, $serversocket);
print "Starting the server...n";
$forkingserver->serve();
print "done.n";
}; if ($@) {
if ($@ =~ m/TException/ and exists $@->{message}) {
my $message = $@->{message};
my $code = $@->{code};
my $out = $code . ':' . $message;
die $out;
} else {
die $@;
}
}
и клиента:
try {
$socket = new TSocket($server_host, $server_port);
$transport = new TBufferedTransport($socket, 1024, 1024);
$protocol = new TBinaryProtocol($transport);
$client = new RPCPerformanceTestClient($protocol);
$transport->open();
$start = microtime(true);
$result = $client->DateToTimestamp('071/26/2011 01:23:45');
var_dump($result);
} catch (Exception $e) {
echo 'Exception: <b>' . $e->getMessage() . '</b>';
}
почему это происходит? Это моя вина? Это ожидаемое поведение?
2 ответов
это часто происходит с протоколами, которые не предоставляют длину сообщения: клиент отправляет больше данных, чем сервер ожидает и ждет, пока сервер получит данные. Сервер получает некоторые данные, пытается проанализировать их и терпит неудачу. Теперь серверная часть протокола находится в ошибочном состоянии. Если он продолжает считывать данные, он может блокировать. Скорее всего, серверная сторона отправила вам некоторый ответ об ошибке и в то же время ожидает получения ответа клиентом, но это будет никогда не бывает.
Это моя догадка. Лучшая стратегия IMHO-установить тайм-аут для клиентских и серверных сокетов.
библиотека PHP бережливости немного сломана. Вам нужно вручную установить тайм-ауты Е. Г.
$socket = new TSocket('host', 9095);
$socket->setSendTimeout(60000);
$socket->setRecvTimeout(60000)