Davide Polato created TIKA-4804:
-----------------------------------
Summary: tika-grpc: fetchAndParseServerSideStreaming never sends
a terminal signal
Key: TIKA-4804
URL: https://issues.apache.org/jira/browse/TIKA-4804
Project: Tika
Issue Type: Bug
Components: tika-pipes
Affects Versions: 3.0.0, 4.0.0
Reporter: Davide Polato
Attachments: TerminalSignalLocalDiagnostic.java
h3. Summary
{{TikaGrpc.fetchAndParseServerSideStreaming}} delivers its reply and then never
closes the call. This happens on the success path, not only on error. gRPC does
not close a call when the handler returns: for a server-streaming method the
server must call {{onCompleted()}}, and this handler never does.
The client sees one message and then waits until its deadline, or forever if it
set none. Each call also leaves server-side call state alive.
h3. Where
{{TikaGrpcServerImpl.fetchAndParseServerSideStreaming}} calls
{{fetchAndParseImpl}} and returns. {{fetchAndParseImpl}} calls only
{{onNext(...)}}.
For contrast, in the same class:
* unary {{fetchAndParse}} calls {{fetchAndParseImpl}} and then
{{onCompleted()}} -- correct
* {{fetchAndParseBiDirectionalStreaming}} forwards the client's {{onCompleted}}
-- correct
Only the server-streaming variant is missing the terminal signal.
h3. Affected versions
Present in every released version that ships tika-grpc: 3.0.0, 3.0.0-BETA2,
3.1.0, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.3.0, 3.3.1, 3.3.2, and the 4.0.0 alpha and
beta tags. The handler has had this shape since the RPC was introduced.
h3. Reproduction
Attached: TerminalSignalLocalDiagnostic.java. Drop it into
tika-grpc/src/test/java/org/apache/tika/pipes/grpc/ and run
{noformat}
mvn -pl tika-grpc test -Dtest=TerminalSignalLocalDiagnostic
{noformat}
It fetches one real file through an in-process server with an async stub and
waits up to 10 seconds for a terminal signal on four RPCs:
{noformat}
v1 fetchAndParse (unary) messages=1 terminal=YES onCompleted
v1 fetchAndParseServerSideStreaming messages=1 terminal=NO -- HUNG
v2 fetchAndParse (unary) messages=1 terminal=YES onCompleted
v2 fetchAndParseServerSideStreaming messages=1 terminal=NO -- HUNG
sanity fetch status = PARSE_SUCCESS
{noformat}
The test then fails in GrpcCleanupExtension with
{noformat}
PostconditionViolationException: One or more Resources couldn't be released
{noformat}
because those two calls are still open. That failure is part of the finding, not
noise: two independent signals, one cause.
h3. Scope notes
* Measured against 4.0.0-SNAPSHOT. The 3.x handlers are structurally identical,
so the same result is expected there, but I have not executed the probe
against
a 3.x build.
* The v2 experimental service (TIKA-4766) inherits the shape from v1. Fixing v1
does not automatically fix v2; both need the terminal signal.
* Found while working on TIKA-4795. Unrelated to that ticket's feature and
independent of it.
h3. Fix
One line per handler: call {{responseObserver.onCompleted()}} after
{{fetchAndParseImpl}}, matching what the unary handler already does. Happy to
put up a patch with a regression test if that is wanted -- the probe above turns
into one directly.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)