"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

中找到更多技术细节