The problem which i am facing has been nagging for a week now and here it is: I have a class AdminBlocageBackgroundProcessing.java which processes a CSV file by reading data from it and validating it and storing it in a array list as:
public Object call( ) {
// TODO Auto-generated method stub
try{
data = ImportMetier.extractFromCSV(
new String(fichier.getFileData(),
"ISO-8859-1"),blocage);
}
catch (Exception e) {
e.printStackTrace();
}
return data;
}
And i am calling it from my action class using :
ServletContext servletContext=getServlet().getServletContext();
ExecutorService execService = (ExecutorService)servletContext.getAttribute("threadPoolAlias");
AdminBlocageBackgroundProcessing adminBlocageBackgroundProcessing= new AdminBlocageBackgroundProcessing(fichier,blocage);
if(status==0 && refreshParam.equals("eventParameter"))
{
future= execService.submit(adminBlocageBackgroundProcessing);
status=1;
autoRefControl=1;
req.setAttribute("CHARGEMENT_EN_COURS","chargement");
return mapping.findForward("self");
}
if(status==1)
{
// for checking if the submitted future task is completed or not
isFutureDone=future.isDone();
if(isFutureDone)
{
data=future.get();
status=0;
System.out.println("Process is Completed");
req.setAttribute("TRAITEMENT_TERMINE","termine");
//sessiondata.putBean(Constantes.BEAN_CONTRATCLIENT_CONTRAT_CLE_FIA, null);
//formulaire.set("refreshParam","" );
execService.shutdown();
isFutureDone=false;
}
else{
System.out.println("Les données sont encore en cours de traitement");
req.setAttribute("CHARGEMENT_EN_ENCORE","encore");
return mapping.findForward("self");
}
}
Now the problem is CSV is having too much data and when we click for importing it, the process is started in background asynchronously but it never gets to completion although have used autorefresh in jsp to maintain the session.
How can we make sure that it is completed although the code is working fine for small data?
but for large data this functionality crumbles and cannot be monitored.
The threadpool which i am using is provided by the container :
public class ThreadPoolServlet implements ServletContextListener
{
public void contextDestroyed(ServletContextEvent arg0) {
final ExecutorService execService = (ExecutorService) arg0.getServletContext().getAttribute("threadPoolAlias");
execService.shutdown();
System.out.println("ServletContextListener destroyed");
// TODO Auto-generated method stub
}
//for initializing the thread pool
public void contextInitialized(ServletContextEvent arg0) {
// TODO Auto-generated method stub
final ExecutorService execService = Executors.newFixedThreadPool(25);
final ServletContext servletContext = arg0.getServletContext();
servletContext.setAttribute("threadPoolAlias", execService);
System.out.println("ServletContextListener started");
}
}
Had a quick look.. your
isFutureDone
depends onstatus
, which is executed right after the submission of the task - which is fairly quick.status
is updated only once, and not updated again. This is fine in the case of very short, seemingly instant, tasks, though it will break for large tasks. It breaks because you use thefuture.get
method conditionally based on theisFutureDone
, which will be false for longer tasks. So you neverget
a result, even though your task completed in the executor. Do away withisFutureDone
. Read up a bit on[Future.get][1]
(both versions [with and without timeout] block, which is what you need here - to wait for the task to finish). It would be a good idea to utilize a timeout in your code that calls the CSV service, to allow for a failure if it takes inappropriately long.