client: closing connection on an infinite streaming response
by Peter Levart
Hi,
I'm trying to use resteasy client (via @RegisterRestClient in Quarkus) to interface a docker (or podman) REST service. It works as a charm for normal REST calls. But there is a call that streams container logs in a specially encoded application/octet-stream. This call has two modes of operation. Either it eventually ends (parameter follow=false) or it may be infinite (parameter follow=true). I modelled the client interface as following:
@Path("/v1.41/libpod")
@ApplicationScoped
@RegisterRestClient(configKey = "btrdkr.podman-service")
public interface LibpodClient {
@GET
@Path("/containers/{name}/logs")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
Response getLogs(
@PathParam("name") String name,
@QueryParam("follow") boolean follow,
@QueryParam("since") Instant since,
@QueryParam("stderr") boolean stderr,
@QueryParam("stdout") boolean stdout,
@QueryParam("tail") int tail,
@QueryParam("timestamps") boolean timestamps
);
I use the returned Response object to obtain an InputStream from:
var in = response.readEntity(InputStream.class);
This works nicely for finite streams. But if I request an infinite stream (follow=true), the returned InputStream, well, never ends. That was the intent, but the user watching such stream eventually decides to terminate it. If I try to close such stream (or the Response), the .close() call blocks forever as it probably tries to consume the stream to the end to prepare HTTP connection to be reused for next request. But in such case (in case of docker/podman service) such connection never going to be reused. So I found a hack that actually works. In case I want to terminate the response on an infinite stream, I cast the Response object to org.jboss.resteasy.specimpl.AbstractBuiltResponse and call .releaseConnection(consumeInputStream: false) on it:
((AbstractBuiltResponse) response).releaseConnection(false);
This closes the client part of connection and docker/podman promptly closes its side too. So my question is whether this is the only way to achieve such behavior in resteasy client or is there another, more official way to do it?
1 year, 5 months