"start_batch was called incorrectly" 在 gRPC 一元调用上
"start_batch was called incorrectly" on gRPC unary call
我从 PHP 这样的代码中进行一元调用:
public function getByIDs(array $ids): array
{
$request = new GetByIDsRequest();
$request->setIDs($ids);
$grpcRequest = $this->client->GetByIDs($request, [], ['timeout' => $this->waitTimeout]);
$response = $this->callWithRetries($grpcRequest);
if (!$response->isOk()) {
$status = $response->getStatus();
throw new GrpcServerException(__FUNCTION__, $status->getDetails(), (int)$status->getCode());
}
... // business logic here
}
private function callWithRetries(\Grpc\UnaryCall $grpcRequest): GrpcUnaryCallResponse
{
$response = null;
for ($attempt = 0; $attempt <= self::$maxRetries; $attempt++) {
if ($attempt > 0) {
usleep(mt_rand(1, 5) * self::$waitBeforeRetry);
}
$response = $this->unaryCall($grpcRequest);
$status = $response->getStatus()->getCode();
if ($response->isOk() || !self::isRetryable($status)) {
return $response;
}
}
return $response;
}
protected function unaryCall(UnaryCall $call): GrpcUnaryCallResponse
{
[$response, $status] = $call->wait();
return new GrpcUnaryCallResponse(
$response,
new GrpcStatus($status)
);
}
有时我会收到 LogicException
消息“start_batch 调用不正确”。任何想法如何处理该异常以及根本原因是什么?
经过一些调查,我发现问题的发生是因为在重试中重用了 \Grpc\UnaryCall
的实例。你不能这样做,否则你会得到一个核心转储。
我们得到 LogicException
而不是核心转储的原因是使用了修补的 gRPC 扩展。
您可以在此 issue
中找到更多技术细节
我从 PHP 这样的代码中进行一元调用:
public function getByIDs(array $ids): array
{
$request = new GetByIDsRequest();
$request->setIDs($ids);
$grpcRequest = $this->client->GetByIDs($request, [], ['timeout' => $this->waitTimeout]);
$response = $this->callWithRetries($grpcRequest);
if (!$response->isOk()) {
$status = $response->getStatus();
throw new GrpcServerException(__FUNCTION__, $status->getDetails(), (int)$status->getCode());
}
... // business logic here
}
private function callWithRetries(\Grpc\UnaryCall $grpcRequest): GrpcUnaryCallResponse
{
$response = null;
for ($attempt = 0; $attempt <= self::$maxRetries; $attempt++) {
if ($attempt > 0) {
usleep(mt_rand(1, 5) * self::$waitBeforeRetry);
}
$response = $this->unaryCall($grpcRequest);
$status = $response->getStatus()->getCode();
if ($response->isOk() || !self::isRetryable($status)) {
return $response;
}
}
return $response;
}
protected function unaryCall(UnaryCall $call): GrpcUnaryCallResponse
{
[$response, $status] = $call->wait();
return new GrpcUnaryCallResponse(
$response,
new GrpcStatus($status)
);
}
有时我会收到 LogicException
消息“start_batch 调用不正确”。任何想法如何处理该异常以及根本原因是什么?
经过一些调查,我发现问题的发生是因为在重试中重用了 \Grpc\UnaryCall
的实例。你不能这样做,否则你会得到一个核心转储。
我们得到 LogicException
而不是核心转储的原因是使用了修补的 gRPC 扩展。
您可以在此 issue
中找到更多技术细节