ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Flow performs slow - is there a better way to handle this?

Post new topic  Reply to topic Goto page Previous  1, 2
 Flow performs slow - is there a better way to handle this? « View previous topic :: View next topic » 
Author Message
fjb_saper
PostPosted: Thu Nov 15, 2007 8:54 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

ADV wrote:
Convert hex to binary

http://lists.xcf.berkeley.edu/lists/advanced-java/1999-February/025946.html


as well check out Integer.decode("0xFF");
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
murdeep
PostPosted: Tue Nov 27, 2007 9:27 am    Post subject: Reply with quote

Master

Joined: 03 Nov 2004
Posts: 211

Ok, I built and tested a JCN to do this.

Here's the code:

Code:
import java.util.ListResourceBundle;

import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.*;

public class AddDelimiter extends MbJavaComputeNode {

   private final static String CRLF_CHARACTERS = "crlfCharacters";
   private final static String RECORD_LENGTH = "recordLength";

   public void evaluate(MbMessageAssembly contact admin) throws MbException {
 
      MbElement msgBody;
       byte[] msgByteIn = null;
      
      
       //get UDP's required to process message
      
      String crlfCharacters = (String)getUserDefinedAttribute(CRLF_CHARACTERS);
      
      if (crlfCharacters == null) {
         MbService.logWarning(this,
               "UDP_Undefined",
               ErrorMessages.MESSAGE_SOURCE,
               ErrorMessages.NO_CRLF_UDP,
               "",
               null);
      }

      Integer recordLength = (Integer)getUserDefinedAttribute(RECORD_LENGTH);
      
      if (recordLength == null) {
         MbService.logWarning(this,
               "UDP_Undefined",
               ErrorMessages.MESSAGE_SOURCE,
               ErrorMessages.NO_RECORD_LENGTH_UDP,
               "",
               null);
      }
      
      // convert delimiter characters to byte[]
      byte[] crlfBytes = new byte[crlfCharacters.length() / 2];
      for (int i = 0; i < crlfBytes.length; i++) {
         crlfBytes[i] = (byte) Integer.parseInt(crlfCharacters.substring(2*i, 2*i+2), 16);
      }
      
      //get node terminals
      MbOutputTerminal out = getOutputTerminal("out");
      MbOutputTerminal alt = getOutputTerminal("alternate");

      //get input message assembly
      MbMessage inMessage = contact admin.getMessage();

      // create new message
      MbMessage outMessage = new MbMessage();
      MbMessageAssembly outAssembly = new MbMessageAssembly(contact admin,
            outMessage);
      
      // copy headers from the input message
      copyMessageHeaders(inMessage, outMessage);
      
      //get message body from input
      msgBody = inMessage.getRootElement().getLastChild();
       msgByteIn = msgBody.toBitstream("","","",0,0,0);
      
       //calculate total records in message (note flow must validate message before calling this JCN
       //flow must ensure that message size is even multiple of record length
       int msgLength = msgByteIn.length;
      int totalRecords = msgLength/recordLength.intValue();
      
      //allocate the new message buffer
      byte[] msgByteOut = new byte[msgLength + (totalRecords*crlfBytes.length)];
      
      //populate the new message buffer copying each record from input message and appending record delimiter
      int currentRecord = 0;
      
      while (currentRecord < totalRecords) {
         System.arraycopy(msgByteIn,currentRecord*recordLength.intValue(),msgByteOut,(currentRecord*(recordLength.intValue()+crlfBytes.length)),recordLength.intValue());
         System.arraycopy(crlfBytes,0,msgByteOut,(currentRecord*(recordLength.intValue()+crlfBytes.length))+recordLength.intValue(),crlfBytes.length);
         currentRecord = currentRecord + 1;
      }

      //get output message root element
      MbElement outRoot = outMessage.getRootElement();

      //Create the output Blob Parser element
      MbElement outParser = outRoot.createElementAsLastChild(MbBLOB.PARSER_NAME);
      MbElement outBodyBLOB = outParser.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "BLOB", msgByteOut);
      
      try { 
         // The following should only be changed
         // if not propagating message to the 'out' terminal
         out.propagate(outAssembly);

      } finally {
         // clear the outMessage
         outMessage.clearMessage();
      }
   }
   
   public void copyMessageHeaders(MbMessage inMessage, MbMessage outMessage) throws MbException
     {
       MbElement outRoot = outMessage.getRootElement();
       MbElement header = inMessage.getRootElement().getFirstChild();

       while(header != null && header.getNextSibling() != null)
         {
           outRoot.addAsLastChild(header.copy());
           header = header.getNextSibling();
         }
     }
   
   public static class ErrorMessages extends ListResourceBundle
   {
      public static final String MESSAGE_SOURCE = ErrorMessages.class.getName();
      public final static String NO_CRLF_UDP = "No crlfCharacters UDP";
      public final static String NO_RECORD_LENGTH_UDP = "No recordLength UDP";
      
      private Object[][] messages =
      {
            {NO_CRLF_UDP,
            "No UDP for: " + CRLF_CHARACTERS
            },
            {NO_RECORD_LENGTH_UDP,
            "No UDP for: " + RECORD_LENGTH
            }
      };
      public Object[][] getContents()
      {
         return messages;
      }
   }
}



Don't know if this is efficient Java but it sure beats the snot out of ESQL. This implementation can dequeue 1.4 4M msgs/second. So the entire transfer detailed above takes about 210 seconds versus ~22000 when using ESQL.

Comments welcome.
Back to top
View user's profile Send private message
kimbert
PostPosted: Tue Nov 27, 2007 3:23 pm    Post subject: Reply with quote

Jedi Council

Joined: 29 Jul 2003
Posts: 5542
Location: Southampton

Clarification: murdeep was encountering a performance defect in ESQL. Not very surprising that Java beats ESQL for his defect scenario. Normally, ESQL and Java have very similar performance, and it is a matter of preference which one you choose.
Back to top
View user's profile Send private message
Ian
PostPosted: Wed Nov 28, 2007 9:49 am    Post subject: Reply with quote

Disciple

Joined: 22 Nov 2002
Posts: 152
Location: London, UK

I have not had a chance to take this ESQL and try it out for myself but I would be interested to know the amount of memory being used by the DataFlowEngine process whilst using the ESQL method ?

I suspect that the memory may be increasing and from a quick look at the ESQL BLOB processing this could be because the heap is being fragmented and it is the cost of the increasing number of new memory allocations that are taking up the processing time.

As my colleague has said, the cost of ESQL and JCN processing are generally comparable or within a percentage of each other. However, in this (specific) case the ESQL processing may be causing fragmentation of the heap and this is what is affecting the processing time.

In this case the solution may be the use of a JCN. If you are interested in understanding the reason why the ESQL method is causing a problem then let me know what the DFE memory usage start and end points are.
_________________
Regards, Ian
Back to top
View user's profile Send private message
murdeep
PostPosted: Wed Nov 28, 2007 10:40 am    Post subject: Reply with quote

Master

Joined: 03 Nov 2004
Posts: 211

Using the ESQL version the DFE memory usage is 76876K at DFE start. When the flow processes a message it ends up at 90056K. As soon as I put another 4M message on the queue it drops to 87000K and then ramps up to ~90056K with peaks at around 92000K. This cycle repeats each time I drop a message on the flow input queue.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page Previous  1, 2 Page 2 of 2

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Flow performs slow - is there a better way to handle this?
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.