Monday, May 9, 2011

FAQ #34 - How to utilize WebLogic Work Managers for long-running ADF processes, Pt. 1

Introduction

The WebLogic Work Manager functionality along with its supporting Java API - CommonJ, can greatly improve performance for those long running processes in your ADF applications, especially for those notorious ones - you know, the one that cause "stuck" threads? This is true because these long running processes can now run asynchronously on a specific Work Manager that you define, one that is configured to ignore "stuck" threads. Let's take a look.


Main Theme

Adding and configuring a Work Manager in WebLogic

You define a Work Manager in WebLogic by selecting Work Managers under the Environment node in the Domain Structure window and clicking New on the Summary of Work Managers page on the right on the Global Work Managers, Request Classes and Constraints table.


On the Select Work Manager Definition type page select Work Manager and click Next.


On the Work Manager Properties page enter the name of the Work Manager and press Next.


On the Select deployment targets page select the Work Manager targets and click Finish to complete the creation of the Work Manager.


The Work Manager will now appear in the Summary of Work Managers table. Click on it to bring up the Configuration page. In it select Ignore Stuck Threads and click Save. This will configure the Work Manager to ignore "stuck" threads for long running processes. We won't be changing the other configuration settings for this Work Manager.



Configuring the Work Manager for your application

To configure the Work Manager for your application, edit the web.xml file and enter the following resource reference:

<resource-ref>
   <res-ref-name>wm/TestWorkManager</res-ref-name>
   <res-type>commonj.work.WorkManager</res-type>
   <res-auth>Container</res-auth>
   <res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>


This is necessary so that you will be able to access the Work Manager programmatically as it shown below.

Programmatically submitting works to the Work Manager


Here is an example of a long running process in an ADF application and a good candidate to produce a "stuck" thread:

    public void selectAll() {
          RowSetIterator iterator = getMyViewObject().createRowSetIterator(null);

          iterator.reset();
         
          // loop over 1,000,000 records...
          while (iterator.hasNext()) {
              MyViewObject myViewObject = (MyViewObject)iterator.next();
              myViewObject.setProcessed(true);
          }
          iterator.closeRowSetIterator();
    }


This is a method in the Application Module that loops over a large number of records - possibly millions - in order to set some boolean flag. Below we will re-write the code using the Work Manager Java API CommonJ.

First you will need to add support for the CommonJ API in your ADF application. The CommonJ API is located in the weblogic.jar library, so use the Libraries and Classpath option in the Project Properties and add it. The library can be found in the wlserver_10.3/server/lib directory in your WebLogic installation directory.


Now modify the method above to the following:

        public void selectAll() {
        try {
          //get Work Manager from local JNDI
          InitialContext ctx = new InitialContext();
          WorkManager workManager = (WorkManager)ctx.lookup("java:comp/env/wm/TestWorkManager");
          //create instance of Work and WorkListener implementations
          Work work = new SelectAllWorkImpl(getMyViewObject().createRowSetIterator(null));
          WorkListener workListener=new SelectAllWorkListener();
          //create work item for execution
          WorkItem workItem = workManager.schedule(work, workListener);
          //create list of WorkItems that we want to execute
          List workItemList=new ArrayList();
          workItemList.add(workItem);
          //run the work items in parallel; don't wait
          workManager.waitForAll(workItemList, WorkManager.IMMEDIATE);
          //check results; use only if you are blocking
          //SelectAllWorkImpl workImpl= (SelectAllWorkImpl)workItem.getResult();
        } catch (NamingException e) {
        } catch (WorkException e) {
        } catch (InterruptedException e) {
        }
    }




Conclusion

In this first installment of discovering Work Managers in WebLogic, we've seen how to create one and how to configure it and use it in your application. We will wrap up this topic on the next installment. There we will explain the code above and provide the implementations of Work and WorkListener interfaces. This is indeed a promising feature that should help in certain cases where long running processes can cause "stuck" threads.

Until the next time, keep on JDeveloping!









5 comments:

  1. Very nice and informative article....

    ReplyDelete
  2. Was there a followup installment with the Work and WorkListener implementations? I wasn't able to find it.
    Thanks.

    ReplyDelete
  3. Never managed to get to it..

    ReplyDelete
  4. where is the followup?

    ReplyDelete
  5. I have 80k records to process, which is divided into 4 batch of 20k. Above solution is best suited for my requirement but not getting idea how to implement below two lines for batches. Can you please explain more on this.
    Work work = new SelectAllWorkImpl(getMyViewObject().createRowSetIterator(null));
    WorkListener workListener=new SelectAllWorkListener();

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...