I am desperately trying to execute a background task in a JEE 8 application running on Tomcat 7.
I want the user to send a request (through a Jersey REST API) and to receive immediately a response whilst the server process a long task.
I've read tones of articles, but none seems to do the trick right...
Here is what I've got so far
public abstract class AbstractService<T extends Entity> {
private final ExecutorService es = Executors.newFixedThreadPool(10);
@Inject
private EntityManager em;
[...]
public void executeAsync(Entity entity) {
es.execute(() -> {
// Do some eavy stuffs on the entity
em.persist(entity);
});
}
}
public class PMyEntityService extends AbstractService<MyEntity> {
[...]
}
That doesn't work because the ExecutorService
doesn't preserve the context, so my injection isn't available inside the child Threads.
So I did like that
public abstract class AbstractService<T extends Entity> {
private final ExecutorService es = Executors.newFixedThreadPool(10);
@Inject
private EntityManager em;
[...]
public void executeAsync(Entity entity) {
es.execute(() -> {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
this.em = emf.createEntityManager();
// Do some eavy stuffs on the entity
em.persist(entity);
emf.close();
});
}
}
public class MyEntityService extends AbstractService<MyEntity> {
[...]
}
Which seems to work well at the first sight, but after many tries, it appears that if I start many simultaneous requests, many ExecutorService
are creating, leading to many EntityManagerFactory
, leading to an overload of connexions to the database.
So I tried to put the ExecutorService
as static
, which doen't work either.
So I've created a new @ApplicationScoped
class with only one static field that is an ExecutorService
... the database connection is still overflowed.
I tried to implement some ManagedExecutorService
but they are only available in javaee-web-api v6.0 while I'm using v8.0.1
I've tried to implement a WorkManager
, didn't work either.
I've put my EntityManagerFactory
as static in an @ApplicationScoped
class, fail again.
...
Please help !