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
Related
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())
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.
I am building a system, where each request from a client side spawns multiple threads on server side. Each thread then is using one or more DAOs (some DAOs can be used by more than one thread at the time). All DAOs are injected (#Autowired) to my thread classes by Spring. Each DAO receives SessionFactory injected as well.
What would be proper way of managing Hibernate sessions across these multiple DAOs so I would not run into problems because of multithreaded environment (e.g. few DAOs from different threads are trying to use the same session at the same time)?
Would be enough that I specify hibernate.current_session_context_class=thread in Hibernate configuration and then everytime in DAO simply use SessionFactory.getCurrentSession() to do the work? Would it properly detect and create sessions per thread as needed?
Yes. It is enough.
When setting hibernate.current_session_context_class to thread , the session returned from SessionFactory.getCurrentSession() is from the ThreadLocal instance.
Every thread will have their own, independently ThreadLocal instance, so different threads will not access to the same hibernate session.
The behaviour of SessionFactory.getCurrentSession() is that: if it is called for the first time in the current thread, a new Session is opened and returned. If it is called again in the same thread, the same session will be returned.
As a result , you can get the same session to use in different DAO methods in the same transaction code by simply calling SessionFactory.getCurrentSession(). It prevents you from passing the Hibernate session through the DAO method 's input parameters in the case that you have to call many different DAO methods in the same transaction code.
When an EJB application receives several requests (work load) it can manage this work load just POOLING the EJBs, so when each EJB object is being used by a thread, the next threads will have to wait queued until some EJB ends up the work (avoiding overloading and efficiency degradation of the system).
Spring is using stateless singletons (not pooling at all) that are used by an "out of control" number of threads.
Is there a way to do something to control the way the work load is going to be delivered? (equivalent to the EJB instance pooling).
Thank you!
In the case of the web app, the servlet container has a pool of threads that determine how many incoming HTTP requests it can handle simultaneously. In the case of the message driven POJO the JMS configuration defines a similar thread pool handing incoming JMS messages. Each of these threads would then access the Spring beans.
Googling around for RMI threading it looks like there is no way to configure thread pooling for RMI. Each RMI client is allocated a thread. In this case you could use Spring's Task Executor framework to do the pooling. Using <task:executor id="executor" pool-size="10"/> in your context config will set up a executor with 10 threads. Then annotate the methods of your Spring bean that will be handling the work with #Async.
Using the Spring task executor you could leave the Servlet and JMS pool configuration alone and configure the pool for your specific work in one place.
To achieve a behaviour similar to the EJB pooling, you could define your own custom scope. Have a look at SimpleThreadScope and the example referenced from this class' javadoc.
The difference between Spring and EJB is, that Spring allows multiple threads on an single instance of an bean, while in EJB you have only one tread per bean (at one point in time).
So you do not need any pooling in Spring for this topic. But on the other hand you need take care that you implement your beans in a threadsave way.
From the comments:
Yes I need it if I want to limit the number of threads that can use my beans simultaneously
One (maybe not the best) way to handle this is to implement the application in normal spring style (no limits). And than have a "front-controller" that accept the client request. But instead of invoking the service directly, it invokes the service asyncron (#Async). May you use some kind of async proxy instead of making the service itselfe asyncron.
class Controller{...
Object doStuff() {return asyncProxy.doStuffAsync().get();}
}
class AsyncProxy{...
#Async Future<Object> duStuffAscny{return service.doStuff();
}
class Service{...
Object doStuff{return new Object();}
}
Then you only need to enable springs Async Support, and there you can configure the Pool used for the Threads.
In this case I would use some kind of front controller, that starts an new Async
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.