I make an unary call from PHP code like that:
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(GrpcUnaryCall $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) ); }
Sometimes I get the LogicException
with message “start_batch was called incorrectly”. Any thoughts how to deal with that exception and what is the root cause?
Advertisement
Answer
After some investigation I found out that the problem occurs because of reusing the instance of GrpcUnaryCall
in retries. You must not do that otherwise you get a core dump.
The reason we got the LogicException
but not a core dump is using a patched gRPC extension.
Some more technical details you can find in this issue