During a benchmark run, we are seeing over 5% of cpu time taken up by each
request creating a new ResteasyUriInfo instance. Please see the attached
For most use cases in our application, the parameters are the same between
requests, and therefore the ResteasyUriInfo are immutable and could be
shared. The case that I can see where sharing a ResteasyUriInfo would be
problematic is when there are path parameters in the URI.
Could it be possible to cache ResteasyUriInfo that are immutable, or even
cache a URI with placeholders for URI that contain path parameters?
IIRC hibernate has a similar caching mechanism for prepared statements with
parameters, a similar approach may work here.
PRINCIPAL SOFTWARE ENGINEER
Red Hat <https://www.redhat.com/>
TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
@redhat <https://twitter.com/redhat> @redhatinc
I was doing some benchmarks with gatling and came across very strange
results where if I have a REST endpoint with normal result types I get
1200 requests per second, but if I return those results inside RxJava's
Single (with Single.just()) I get about 250 requests per second, and if
I change that with CompletionStage (using
CompletableFuture.completedFuture()) I get about 310 requests per second.
Frankly I'm not sure how to go about finding out why we have such a
difference, and whether we can mitigate it, but we should definitely
try. How do you usually tackle these problems? Any help?
I was looking into RESTEASY-2038 . I'm not sure how to handle this
correctly so I need to know your opinion.
In the *org.jboss.resteasy.client.jaxrs.cache.CacheInterceptor* there is a
method for storing response in the cache containing this part.
*String contentType = (String)
*byte cached = ReadFromStream.readFromStream(1024,
*MediaType mediaType = MediaType.valueOf(contentType);*
*final BrowserCache.Entry entry = cache.put(request.getUri().toString(),
* response.getHeaders(), cached, expires, etag, lastModified);*
Later, once the same GET method is executed, the interceptor checks if
there is an entry in the cache for the given Accept type.
*BrowserCache.Entry entry = getEntry(request);*
In the getEntry method it checks for the type
*entry = cache.get(uri, accept);*
*if (entry != null) return entry;*
* entry = cache.get(uri, accept.withCharset("UTF-8"));*
* if (entry != null) return entry;*
Let's assume that resource returns XML data with Content-Type:
and the client sends Accept: application/xml
So the very first request adds into the cache entry for
application/xml;charset=UTF-8 because it is taken from Content-Type header.
Subsequent request gets the cached value (expecting that entry is not
expired), although it cannot find it under application/xml, it is found
under application/xml;charset=UTF-8 because of this:
The problem is if decide to change the code to use Accept instead of
current Content-Type, we can't be sure if there is Accept header in the
request and we're not sure about response encoding.
Also the statement in Jira regarding content type mismatch: like Accept is
application/json, but resource returns application/xml and to store it
under application/json instead of application/xml is IMHO wrong (coding
issue). I believe that it should be stored per actual content type.
For RESTEASY-2041 "Refactor scopes for Servlet API jar" I want to write
tests that use netty and undertow, but I'm not sure where to put them.
They clearly don't go in testsuite/integration-tests, and it's not clear
that they go in testsuite/unit-tests, which doesn't reference
resteasy-netty, resteasy-netty4, or resteasy-undertow. Seems a little
crazy to create a new module just for one test.
And they can't go in resteasy-netty, resteasy-netty4, or
resteasy-undertow, because the point of the tests is to check that each
of them "exports" jboss-servlet-api_3.1_spec to other modules.
I'm leaning towards testsuite/unit-tests.
My company's smarter than your company (unless you work for Red Hat)
At the moment, the resteasy-rxjava and resteasy-rxjava2 modules register
hooks into the rxjava and rxjava2 plugin/hook system, in order to
propagate the RESTEasy context (thread-local) into all phases of rxjava
single/flowable/etc, which can otherwise be scheduled on any
scheduler/thread and so would lose the RESTEasy context.
RxJava being what it is, you can only register a single plugin/hook
globally, so if RESTEasy defines it, nobody else can. That's
problematic, because CDI also requires context propagation, and so does
Redpipe (to name just the two examples I am using ATM), so I created a
library called Reactive Contexts which decouples libraries that have a
context to propagate (RESTEasy, CDI, Redpipe, etc…) and libraries that
provide context propagation (RxJava1, 2, etc…).
That library is super small (4k core, 13k propagator for rxjava). I'd
like to remove the custom context propagation in the
resteasy-rxjava/rxjava2 and make those modules depend on a new
resteasy-reactive-context which would depend on reactive-contexts-core
to provide a context provider for RESTEasy.
This way, I can also make CDI and Redpipe provide such a module and all
those contexts will be propagated for rxjava for all users :)
WDYT? Do you agree on that extra dependency ? It's only for the rxjava
modules, not the core.