Handling Concurrent Servlet Requests on Domino Server - xpages

I am trying to create a REST service using a Servlet that lives inside an NSF. The Servlet runs but I noticed that it handles requests one at a time, so if a request is waiting for a database query to finish, all other requests must wait. I know that requests for Servlets on Tomcat or Glassfish get their own thread but that doesn't seem to be happening on the Domino server.
To try and get around this I tried to spawn new threads inside the Servlet but kept getting NotesContext not initialized errors. I searched around and found a project called Threads and Jobs, and intended to use the code there to create a Servlet that spawns new threads and gives the client a requestId and requires them to poll to retrieve the job results, or listen on a port that the server will broadcast on when finished. When I tried to import the project and run it as is, the pages Thread.xsp and Job.xsp rendered but weren't functional. I get the following output in the console:
Thread started
>> Thread running
java.lang.NullPointerException
at com.ibm.domino.xsp.module.nsf.NotesContext.getRunningModule(NotesContext.java:394)
at com.ibm.domino.xsp.module.nsf.NotesContext.checkSignerRightsNonXSP(NotesContext.java:960)
at com.ibm.domino.xsp.module.nsf.ModuleClassLoader$DynamicClassLoader.loadClass(ModuleClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:626)
at org.openntf.samples.thread.ThreadSample$MyThread$1.run(ThreadSample.java:86)
at org.openntf.samples.thread.ThreadSample$MyThread$1.run(ThreadSample.java:1)
at com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor$3.run(ThreadSessionExecutor.java:156)
at java.security.AccessController.doPrivileged(AccessController.java:310)
at com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor.run(ThreadSessionExecutor.java:154)
at org.openntf.samples.thread.ThreadSample$MyThread.run(ThreadSample.java:123)
>> Thread running
java.lang.NoClassDefFoundError: lotus/domino/Session
at org.openntf.samples.thread.ThreadSample$MyThread$1.run(ThreadSample.java:86)
at org.openntf.samples.thread.ThreadSample$MyThread$1.run(ThreadSample.java:1)
at com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor$3.run(ThreadSessionExecutor.java:156)
at java.security.AccessController.doPrivileged(AccessController.java:310)
at com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor.run(ThreadSessionExecutor.java:154)
at org.openntf.samples.thread.ThreadSample$MyThread.run(ThreadSample.java:123)
>> Thread stopping
Thread left

You need to design the servlet as OSGi plug-in otherwise it doesn't find the Domino classes. Check this sample for code samples, also have a look at my code for threads and check out Serdar's project on OpenNTF/GitHub
Let us know how it goes.

Related

How does resttemplate.exchange() execute on a different thread?

It is my understanding that call to exchange method of resttemplate executes on a different thread. Basically all client libraries execute on a different thread.
Let's say my servlet container is tomcat. When a request is made to the endpoint exposed, tomcat thread recieves the request and the request comes to service layer from controller layer on the same thread. In the service layer, I have a call to 3rd party service using resttemplate. When exchange method is invoked, internally the operation runs on different thread and gets the result of the operation.
I have a question regarding this:
Where does the resttemplate get the thread from basically from which thread pool to execute on a different thread ?
I would like to know if executing resttemplate on a different thread has got to do anything with tomcat thread pool.
Can anybody shed some lights on this?
When a request is made to the endpoint exposed, tomcat thread recieves
the request and the request comes to service layer from controller
layer on the same thread.
This happens only if tomcat and java applications are in same JVM (like in embedded tomcat). Otherwise, by default, Java threads are created and destroyed without being pooled. Of course, you can create a java thread pool too.
Every time a third-party API is called via RestTemplate it will create new Httpconnection and will close it once it is done. You can create RestTemplate's own connection pool using HttpComponentsClientHttpRequestFactory like so:
new org.springframework.web.client.RestTemplate(new HttpComponentsClientHttpRequestFactory())

Continue JSP execution after sending HTTP response

How can I have a JSP page send a HTTP response to the client, and then keep executing?
I have a JSP page that has to execute a long request which generates a report with large amounts of data and saves it to disk. This normally takes minutes to complete. This JSP page is called by an application that I have no control over.
This application has a timeout delay shorter than 45 seconds and therefore each request to a JSP page is resulting in a timeout. Therefore, I need the JSP page to send the complete HTTP response to the client as fast as possible (ideally, as soon as the input parameters have been validated), and then run the process to generate the report and saving it to disk afterward.
Should I open a separate thread to generate the report? This way, the response is sent back to the client, while the thread is still running. Is there any other way with which I can achieve this?
A JSP is a view, not a controller. It is not the preferred place to perform work.
By definition, the JSP bytes are the output, so you cannot expect to do synchronous (on same thread) work in java directive tags after the end of the jsp. Well, unless you prematurely close the response in a java directive tag... But that is unclean (expect trashing your server logs with error messages...)
The spun thread trick only works if you can even start a thread (not all container would allow that). And if you can, you run into the risk of attacks; you would need to control how many threads are allowed. That means having a pool in the context, and implementing a fail-fast if all threads are busy.
This can take the form of a ThreadPoolExecutor (that you woul dlazily install in the servlet context), constructed with a blockingqueue with a small limit, to which you submit() your task but handling that it can be rejected (and failing with a suitable message to the user).
Read carefully the Queueing part of the ThreadPoolExecutor.
Of course, you can toy with onTimer() on the javascript side to pool for the progress, or to cancel (all that with a token in the session for the running task of course).

How to run a time consuming task on startup in a web application while deploying it

we are facing an issue with initializing our cache at server startup or application deployment. Initializing the cache involves
Querying a database to get the list of items
Making an rmi call for each item
Listening to the data on a JMS queue/topic
Constructing the cache
This initialization process is in startup code. All this is taking lot of time due to which the deployment is taking lot of time or server start time is increasing.
So what I proposed is to create a thread in the startup and run the initialization code in it. I wrote a sample application to demonstrate it.
It involves a ServletContextListener, a filter. In the listener I am creating a new thread in which the HeavyProcess will run. When it finishes an event will be fired which the filter will be listening. On receiving the event the filter will allow incoming http requests. Until then the filter redirects all clients to a default page which shows a message that the application is initializing.
I presented this approach and few concerns were raised.
We should not ideally create a thread because handling the thread will be difficult.
My question is why cant we create a thread like these in web applications.
If this is not good, then what is the best approach?
If you can use managed threads, avoid unmanaged ones. The container has no control over unmanaged threads, and unmanaged threads survive redeployments, if you do not terminate these properly. So you have to register unmanaged threads, and terminate these somehow (which is not easy as well, because you have to handle race-conditions carefully).
So one solution is to use #Startup, and something like this:
#Schedule(second = "*/45", minute = "*", hour = "*")
protected void asyncInit(final Timer timer) {
timer.cancel();
// Do init here
// Set flag that init has been completed
}
I have learned about this method here: Executing task after deployment of Java EE application
So this gives you an async managed thread, and deployment will not be delayed by #PostConstruct. Note the timer.cancel().
Looking at your actual problem: I suggest using a cache which supports "warm starts".
For example, Infinispan supports cache stores so that the cache content survives restarts. If you have a cluster, there are distributed or replicated caching modes as well.
JBoss 7 embeds Infinispan (it's an integrated service in the same JVM), but it can be operated independently as well.
Another candidate is Redis (and any other key/value store with persistence will do as well).
In general, creating unmanaged threads in a Java EE environment is a bad idea. You will loose container managed transactions, user context and many more Java EE concepts within your unmanaged thread. Additionally unmanaged threads may block the conainer on shutdown if your thread handling isn't appropriate.
Which Java EE Version are you using? Perhaps you can use Servlet 3.0's async feature?
Or call a asynchronous EJB for doing the heavy stuff at startup (#PostConstruct). The call will then set a flag when its job is done.

Prevent thread blocking in Tomcat

I have a Java servlet that acts as a facade to other webservices deployed on the same Tomcat instance. My wrapper servlet creates N more threads, each which invokes a webservice, collates the response and sends it back to the client. The webservices are deployed all on the same Tomcat instance as different applications.
I am seeing thread blocking on this facade wrapper service after a few hours of deployment which brings down the Tomcat instance. All blocked threads are endpoints to this facade webservice (like http://domain/appContext/facadeService)
Is there a way to control such thread-blocking, due to starvation of available threads that actually do the processing? What are the best practices to prevent such deadlocks?
The common solution to this problem is to use the Executor framework. You need to express your web service call as Callable and pass it to the executor either as it stands, or as a Collection<Callable> (see the Javadoc for complete list of options).
You have two choices to control the time. First is to use parameters of an appropriate method of the Executor class where you specify the max web service timeout. Another option is to do get the result (which is expressed as Future<T>) and use .get(long, TimeUnit) to specify the maximum amount of time you can wait for a result.

Hibernate session in threads

Im having some problem with a service that acts as a listener of some events that are originated from an external library, that library creates a thread for reading comm port and send back the data to my listener (the grails service) on certain cases.
The problem is that i cannot update the database when methods are called from the reading thread becose grails bound the hibernate session to threads.
There is any chance to get the hibernate session for that thread??
There is a configuration parameter to propagate or inject the session to threads??
i have seen the background thread plugin but it seems that is only useful if the thread is created by grails.
I think you are not getting a session because your service is not being invoked as part of a standard http request.
Grails has some convenience methods like
withSession
withNewSession
withTransaction
that might fit the bill

Resources