Hi David,
Thanks for the very valuable feed-back. Here are the changes that I just
made to SVN trunk:
- Fixed Javadocs of ClientResource#release() and Message#release()
- Request and responses now call their release() method upon garbage
collection. It releases any associated entity
- InputRepresentation#getText() now closes the underlying stream
- Representation#exhaust() now closes the underlying stream used
- Increased default value for "maxConnectionsPerHost" parameter of the
Apache HTTP client extension from "2" to "10"
Here is an updated version of your example:
ClientResource resource = new ClientResource("
http://www.restlet.org/SomeResourcePath.html");
try {
String doc = resource.get().getText();
}
catch (ResourceException e) {
//log it here
resource.getResponse().release();
}
I've also added a section at the end of ClientResource in the wiki:
http://wiki.restlet.org/docs_2.0/13-restlet/27-restlet/328-restlet/285-restlet.html
All those changes will be in 2.0.0.
Best regards,
Jerome
2010/7/19 David Fogel <[email protected]>
> Hi Jerome-
>
> (comments inline)
>
> On Sun, Jul 18, 2010 at 10:05 AM, Jerome Louvel
> <[email protected]> wrote:
> > As Thierry pointed out, Representation#release() will
> > close the stream immediately in your case.
>
> I'm still trying to understand what the correct way is to use the
> ClientResource API. The problem I described in my initial message is
> when we get a 404 response, which causes ClientResource.get() to throw
> a ResourceException. My assumption is that we aren't even guaranteed
> to get a response entity at all for a 404 (the HTTP spec says the
> server SHOULD return an entity).
>
> So, based on what you and Thierry have said, a correct usage of the
> ClientResource API would have to be something like:
>
> ClientResource resource = new
> ClientResource("http://www.restlet.org/SomeResourcePath.html");
> String doc = null;
> try {
> Representation result = resource.get();
>
> doc = result.getText();
>
> result.release();
> }
> catch (ResourceException e) {
> Representation entity = resource.getResponseEntity();
> if (entity != null)
> entity.release();
> }
>
> or, I suppose it could be written like this:
>
> ClientResource resource = new
> ClientResource("http://www.restlet.org/SomeResourcePath.html");
> String doc = null;
> try {
>
> doc = resource.get().getText();
> }
> catch (ResourceException e) {
> //log it here
> }
> finally {
> Representation entity = resource.getResponseEntity();
> if (entity != null)
> entity.release();
> }
>
> If this is the design, then okay. But in the examples showing
> ClientResource usage in the documentation (the First Resource article,
> the Tutorial article, or the ClientResource API wiki page), NONE of
> them show any exception handling or calls to release(). And since the
> built-in client connector works fine (as far as we've seen) without
> calling release(), it is strange that using the same approach with one
> of the other included connectors causes complete thread hanging. I
> think there should be one recommended way to use an API, and it should
> work with all implementations of that API- after all, that's the
> purpose of any API!
>
> Additionally (and maybe this is just an issue with HTTPClient) it
> doesn't seem very desirable to have calls simply block indefinitely
> when waiting for a pooled connection object to become available.
> Perhaps there should be some sort of time-out? Or perhaps there's a
> different way to configure httpclient for default Restlet integration?
>
> > You can't expect ClientResource#release to do it for you
> > as it would have to keep track of all requests sent by it
> > and pending processing.
>
> ClientResource extends UniformResource, which, according to the
> javadocs, encapsulates a Request and Response object. Since most of
> the methods on UniformResource and ClientResource have to do with
> accessing and manipulating the _current_ Request and Response objects,
> why isn't it reasonable to expect that ClientResource.release()
> release the current Response's entity?
>
> Also, the current javadoc for the UniformResource.release() method says:
>
> Releases the resource. First calls the {...@link #doRelease()} method then
> {...@link Request#release()} and finally {...@link Response#release()}.
>
> which I think may not be the case any longer, looking at the code, but
> at any rate it claims it will call Response.release(), which is
> defined in Message.release(), and which, by default, calls
> getEntity().release(). So, there are an awful lot of different
> "release" methods.
>
> > Also, Representation#getText() and Representation#exhaust()
> > shouldn't systematically release the representation as it would
> > prevent it from being reuse several time.
>
> Is it reasonable to expect them to close the InputStream or Reader
> they use to fetch the text? InputStreams and Readers are not
> generally re-usable, concurrently or sequentially.
>
> Thanks,
> -Dave Fogel
>
> ------------------------------------------------------
>
> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2635269
>
------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2635339