Announcement Announcement Module
Collapse
No announcement yet.
Asynchronous process Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Asynchronous process

    Can someone recommend a good way to handle a long running process in a web application that's kicked off by a Struts action? I want to handle this asynchronously. So, the user clicks a button, an action calls a non-blocking process to run the long running process, and a page with the status of the process is returned to the user. What would be the best way to implement this non-blocking call? JMS? MDB? Spring Batch? Once the process has completed, is there a nice way to notify the calling user's session?

    Thanks,
    Jeff

  • #2
    You could have a look at the following post:

    http://pveentjer.wordpress.com/2007/...-task-from-ui/

    Comment


    • #3
      Thanks for the link Alarmnummer. It seems that your post suggests spawning a new thread to execute the long running process. Isn't it advisable to avoid spawning threads from a web app? Doing so complicates JNDI contexts and probably has other serious drawbacks. Is there another approach that's generally suggested/used for Java web applications? Or am I being to idealistic. Perhaps spawning a thread, even if it does have drawbacks, is the most practical approach. What do you think?

      Thanks.
      Last edited by jaypee; Apr 4th, 2008, 09:33 AM.

      Comment


      • #4
        Originally posted by jaypee View Post
        Thanks for the link Alarmnummer. It seems that your post suggests spawning a new thread to execute the long running process. Isn't it advisable to avoid spawning threads from a web app? Doing so complicates JNDI contexts and probably has other serious drawbacks.
        It depends on the situation. If you are using EJB you could get in troubles (because resources are not set like transactions). But if you are using Spring, the quality of the solution depends on the quality of the implementation of the java code itself. Not on some ridiculous restricting container.

        Is there another approach that's generally suggested/used for Java web applications? Or am I being to idealistic.
        Not idealistic, but influenced by the limitations of the classic J2EE platform.

        Perhaps spawning a thread, even if it does have drawbacks, is the most practical approach. What do you think?
        It depends on the situation. But correctly design multithreaded code is perfectly safe to use in a servlet container (I'm doing it for years).

        Comment


        • #5
          Ok. I'll give it a try and see how it goes. Thanks again.

          Beside thread spawning, the other options seem to be JMS+Message Driven Bean (MDB) and JMS+scheduler (Quartz, Spring Batch, etc.). Out of curiousity, what do you (everyone out there reading this) think about the JMS+Message Driven Bean approach for this problem? Is it overengineered?

          http://www.javaranch.com/journal/200...mServlets.html

          Oh, I should also ask, if I spawn a new thread, how would I provide that thread with an argument on which to operate? Is it best for the spawner to write any arguments to a database and then have the thread read them from the database? I suppose passing JMS messages between threads is another option. And what about passing Spring and Hibernate contexts into the new thread? Hmm...
          Last edited by jaypee; Apr 4th, 2008, 04:16 PM.

          Comment


          • #6
            Originally posted by jaypee View Post
            Ok. I'll give it a try and see how it goes. Thanks again.

            Beside thread spawning, the other options seem to be JMS+Message Driven Bean (MDB) and JMS+scheduler (Quartz, Spring Batch, etc.). Out of curiousity, what do you (everyone out there reading this) think about the JMS+Message Driven Bean approach for this problem? Is it overengineered?
            Jup.. overkill

            Oh, I should also ask, if I spawn a new thread, how would I provide that thread with an argument on which to operate?
            Focus on tasks (runnable's) and not on threads. You can create Runnable that gets injected with all dependencies needed. The Runnable can be created by some Factory that can be injected with the the dependencies of the runnable, and the factory itself can be injected in the 'controlller' so it is able to create. All call specific data can be passed to the factory using the create method.

            Runnable task = deletePersonTaskFactory.create(request.get("person Id"));

            And the task can be executed by an Executor (also to be injected in the controller).

            executor.execute(task);

            See the post for more info.


            And what about passing Spring and Hibernate contexts into the new thread? Hmm...
            No problem. When you 'jump' through a Service, a transaction can be attached.

            Code:
            class DeleteEmployeeTask implements RUnnable{
               private EmployeeService service;
               private int employeeId;
               ...constructor
            
                public void run(){
                     try{
                           service.delete(employeeId);
                     }catch(Exception ex){
                           ..log it
                     }
                }
            }
            The EmployeeService puts a transaction around the call. Using threading this way, doesn't make it any different in the way an ordinary servlet-container-thread calls from the controller some Service, and that is how I like my threads: lightweight - not introducing the need to complicate a simple design.
            Last edited by Alarmnummer; Apr 5th, 2008, 12:46 PM.

            Comment


            • #7
              Alarmnummer,

              Your solution works well. Thanks again for your help.

              Comment

              Working...
              X