users@jersey.java.net

Re: [Jersey] Using client apis on server (or calling a REST service from a REST service)

From: Craig McClanahan <craigmcc_at_gmail.com>
Date: Mon, 2 Nov 2009 14:54:10 -0800

On Mon, Nov 2, 2009 at 2:08 PM, Andrew Ochsner <aochsner_at_cs.stanford.edu> wrote:
> Hi:
>
> Given that Client instances are expensive to create, is there a good
> solution/approach to creating/destroying these in the context of a Resource
> (which currently is using per-thread instantiation)?  I'm not doing anything
> complicated, just curious if there's a best practice for these sorts of
> things
>
> Thanks
> Andy O
>

I would take a look at instantiating a single client instance (for
each server that you need to contact), and storing these instances in
application scope (i.e. servlet context attributes in a webapp) and
then use them to create new WebResource instances on the fly in your
resource methods. As long as you don't try wild things like changing
the set of filters associated with a client on the fly, creating new
WebResource instances should be threadsafe.

Another alternative would be to precreate a pool of Client instances,
and have your resource methods "check out" a client instance, use it,
and check it back in -- analogous to the way that JDBC connection
pools work. You'd ideally want to have the pool dynamically
expandable up to the maximum number of simultaneous request processing
threads you are configured for, or precreate that many of them ahead
of time.

A third choice would be to use a thread local variable containing
Client instances, keyed by the current thread (Thread. in your
resource classes (probably in an abstract base class to centralize the
logic), and only create a Client instance the first time a particular
request thread needs one. The tricky part of this approach, however,
is how to clean up these Client instances. A ServletContextListener
can help you deal with application shutdown, but I don't see any
reliable way to deal with the fact that your servlet container might
decide to throw away a request processing thread (instead of pooling
and reusing them) any time it wants to -- with no notification to your
app that this thread is no longer in use, so any Client instance
cached for it can be thrown away.

Craig