I am creating a Grizzly http server in a Java SE application, pointing to a Resource package with a class that processes the @GET
calls from the browser.
By default, Grizzly starts up to 16 threads (0-15) before cycling back around to thread 0 again. Each time these threads are initalised (and, it seems, even when it goes back to thread 0 again), it calls the constructor on the resource class - i.e. the constructor is being called on EVERY GET Request, not just the first one or even just the first 16 (one for each thread).
My constructor creates a Kafka Streams data store, which can't be initialized multiple times (well, I could assign a random identifier each time, but then I'd still get a conflict eventually), so I want to create it once and have it be accessible from all threads.
Is there a simple way to do this in the resource code itself, or am I better off creating the data store elsewhere, and doing some kind of cross-thread call to get the information (in which case, is there any way to inject that reference into the Resource code, e.g. pass it into the constructor?)
Alternatively, can I get Grizzly to keep the objects alive somehow so it doesn't need to keep calling the constructor? What are the pitfalls of that approach, if it's even possible?
Current Code:
Server created and started as follows:
public static HttpServer startServer()
{
final ResourceConfig rc = new ResourceConfig().packages("com.project.resource.provider");
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
return server;
}
JAX-RS resource:
@Path("/GetFromHere")
public class GetFromHereProvider // in package com.project.resource.provider
{
private final ReadOnlyKeyValueStore<String,DetailObject> kafkaDetailObjectStore;
public GetFromHereProvider() throws Exception
{
// create kafka streams objects and populate kafkaDetailObjectStore. This is being called on every GET request too, for some reason.
}
@GET
@Path("{id}")
@Produces(MediaType.TEXT_PLAIN)
public String getObject(@PathParam("id") String objectID)
{
DetailObject obj= kafkaDetailObjectStore(objectID);
return (obj == null ? "" : obj.toString());
}
}