| Author | 
		  Message
		 | 
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 3:27 am    Post subject: message through out1 terminal using ROUTING:BEGIN ATOMIC | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				Hi guys,
 
 
I have made a flow where i am using shared row and store my result in cache memory and then parse the message through out1 terminal of compute node
 
 
the esql is 
 
 
 
ROUTING : BEGIN ATOMIC -- beginning of atomic block. Processing is single threaded until the END; is reached
 
			IF CacheQueueTable.valid IS NULL THEN
 
		 		SET  CacheQueueTable.DestinationData[] =  
 
		       	(Select emp.email as TERMNO from Database.EMP_DETAILS as emp WHERE emp.name = 'nikhil'); 
 
		         	 
 
			SET CacheQueueTable.valid = true;
 
			END IF;		
 
	
 
		--Fetching data from Cache Table
 
	
 
		set terminalnumber = the(Select emp.email as TERMNO from CacheQueueTable.DestinationData[] as emp WHERE emp.name = 'nikhil');
 
		          
 
		END ROUTING ; -- end of the ROUTING atomic block
 
 
the query returns the terminal number and initially i used PROPOGATE TO TERMINAL terminalnumber;
 
But its not working. 
 
 
Is there any other way to set the terminal. | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | Vitor | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 3:30 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		    Grand High Poobah
 
 Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA 
  | 
		  
		    
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | mqjeff | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 3:31 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Grand Master
 
 Joined: 25 Jun 2008 Posts: 17447
  
  | 
		  
		    
			  
				| The easiest way to make many people here unwilling to help you is to say "it is not working", and then fail to describe any symptoms or provide any information about what it currently does or what you expect it to be doing instead. | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 6:03 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				hi vitor , 
 
please ignore the previous post that u mentioned ....the requirement changed .....so please follow this post...
 
 
I was also thinkin of using WMQ for this but some how it cannnot be used here.
 
 
hi jeff...sorry for not giving the full info....
 
 
Actually i am making a TCP Application, there will be 1 send flow and multilple output flow (or recieve flow)
 
 
Send Flow 
 
FileInput -->Compute--> TCPClientOutput
 
 
Recieve Flow
 
TCPServerInput --> FileOutput
 
 
there are multiple TCPClientOutput connected to different terminals (out1,2....) of compute node. 
 
 
 
In the Compute node I have to set the Database Table data into the Cache memory and then everytime i have to fetch data from this cache memory. I am using atomic Block so that the code is hit only once at a time
 
 
The Data will contain the IP address , PortNumber and terminal name (out1,2...) of each TCPClientOutput. 
 
 
So I want to know how can i push the message to flow into that particular terminal. 
 
 
I know we can use PROPOGATE statement for this but i have read somewhr that i should not be used when using Atomic block | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | smdavies99 | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 6:37 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		    Jedi Council
 
 Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land. 
  | 
		  
		    
			  
				I worked on a project where we had to distribute the output to between 1 & 5 Output Queues. There were 2 or 3 instances of the input flow so there had to be some sync between them in order to keep the distribution model flat.
 
 
I used an ESQL procedure and returned the Q number as part of the call to the Procedure.
 
Inside the procedure, it had a
 
 
 Begin Atomic
 
   .
 
   .
 
   .
 
  End
 
While it got the next q number to use and if it needed to wrap then it reset the q number as appropriate.
 
 
This gave us an even distribution of numbers. The number was used to generate the string that contained the Output Queue Name for sending the messages.
 
 
You are on right track. In your case, you can use the returned number to decide which terminal to propagate to.
 
Don't forget to have a defult Propagate just in case for some reason, the number that was returned was out of range....
 
    _________________ WMQ User since 1999
 
MQSI/WBI/WMB/'Thingy' User since 2002
 
Linux user since 1995
 
 
 
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 10:03 pm    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				| Hi Davies.....I cant use MQ here as the other application does not recognise MQ....so have to use TCP here.....i just want to know how to pass the message in desired out terminal of compute node when using atomic block ..... | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 10:13 pm    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				| sorry davies i guess i misunderstood you ....i get the out terminal name (i.e out1 , 2....) but i dnt know how to set it in this case  ....i cnt use PROPAGATE statement here ....so wht other ways are there to set it | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | smdavies99 | 
		  
		    
			  
				 Posted: Tue Jan 27, 2009 11:44 pm    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		    Jedi Council
 
 Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land. 
  | 
		  
		    
			  
				It does not matter if the input node is MQ or TCP the idea is the same.
 
I was trying to illustrate how I had used this sort of thing successfully.
 
 
 
[code]
 
    Declare Forward_terminal Integer;
 
    SET OutputRoot = InputRoot;
 
    
 
    set Forward_terminal = 0; 
 
    call get_Terminal(Forward_terminal);
 
 
    if Forward_terminal = 1 then PROPAGATE to Terminal 'out1'; end if;
 
    if Forward_terminal = 2 then PROPAGATE to Terminal 'out2'; end if;
 
 
    -- 
 
    -- If for some reason we get here then by default use terminal 1
 
    --
 
    PROPAGATE to Terminal 'out1';
 
 
[/code]
 
You could use a case statement instead of 'If....end if'.
 
 
Get_terminal is where you do the 
 
[code]
 
    BEGIN ATOMIC
 
    .
 
    .
 
    .
 
    END;
 
 
[/code]
 
This is an externally callable bit of ESQL that is available to all flows in the EG.
 
The current value for the return result is stored in a shared variable. The Atomic section just syncs the increments to the value between flows/instances.
 
 
Does the above help a bit? _________________ WMQ User since 1999
 
MQSI/WBI/WMB/'Thingy' User since 2002
 
Linux user since 1995
 
 
 
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 1:16 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				hi davies ...i got your point .....thanks a ton man ....i will let you know the result ...and want to ask 2 things more if its fine with you....i am pretty new to broker and esql
 
 
1. when i call the procedure call get_Terminal(Forward_terminal) ...what is the return value that i get...i am sure it gives the terminal name...but how this is done...
 
 
2. I am stuck at one more point - I set the table in cache memory using shared variable but i am not able to fetch the value from the cache memory...below is the esql
 
 
declare CacheQueueTable SHARED ROW; -- a shared variable that can be used by instances of a flow
 
CREATE COMPUTE MODULE MF_TCP_SEND_Compute
 
	CREATE FUNCTION Main() RETURNS BOOLEAN
 
	BEGIN
 
		
 
		declare terminalnumber character;
 
		declare portnumber character;
 
 
ROUTING : BEGIN ATOMIC -- beginning of atomic block. Processing is single threaded until the END; is reached
 
		IF CacheQueueTable.valid IS NULL THEN
 
		 		SET  CacheQueueTable.DestinationData[] =  
 
		       	(Select emp.email as TERMNO,emp.name as portno from Database.EMP_DETAILS as emp WHERE emp.name = 'nikhil');
 
		  
 
		  SET CacheQueueTable.valid = true;
 
		END IF;		
 
	
 
		--Fetching data from Cache Table
 
	
 
		set OutputRoot.XMLNS.TCPSEND.TCP[] = (Select emp.email as TERMNO,emp.name as portno from CacheQueueTable.DestinationData[] as emp WHERE emp.name = 'nikhil');
 
		SET  terminalnumber = OutputRoot.XMLNS.TCPSEND.TCP[1].TERMNO;
 
		set portnumber = OutputRoot.XMLNS.TCPSEND.TCP[1].portno;
 
 
END ROUTING ; -- end of the ROUTING atomic block
 
		
 
		-- CALL CopyMessageHeaders();
 
		-- CALL CopyEntireMessage();
 
		RETURN TRUE;
 
	END; | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rekarm01 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 2:10 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Grand Master
 
 Joined: 25 Jun 2008 Posts: 1415
  
  | 
		  
		    
			  
				
   
	| rohank84 wrote: | 
   
  
	So I want to know how can i push the message to flow into that particular terminal. 
 
 
I know we can use PROPOGATE statement for this but i have read somewhr that i should not be used when using Atomic block | 
   
 
 
You should not use a PROPAGATE statement from within an ATOMIC block.  But you're still free to use PROPAGATE statements outside of any ATOMIC blocks.
 
 
   
	| rohank84 wrote: | 
   
  
	
   
	| Code: | 
   
  
	ROUTING : BEGIN ATOMIC -- beginning of atomic block. Processing is single threaded until the END; is reached
 
    IF CacheQueueTable.valid IS NULL THEN
 
        SET CacheQueueTable.DestinationData[] =
 
            (Select emp.email as TERMNO,emp.name as portno
 
            from Database.EMP_DETAILS as emp
 
            WHERE emp.name = 'nikhil');
 
 
        SET CacheQueueTable.valid = true;
 
    END IF; | 
   
 
 | 
   
 
Right here would be a good place to end your ATOMIC block, since you appear to be done modifying CacheQueueTable.
 
 
I'm not quite sure what this code is supposed to do:
   
	| rohank84 wrote: | 
   
  
	
   
	| Code: | 
   
  
	--Fetching data from Cache Table
 
 
set OutputRoot.XMLNS.TCPSEND.TCP[] =
 
    (Select emp.email as TERMNO,emp.name as portno
 
    from CacheQueueTable.DestinationData[] as emp
 
    WHERE emp.name = 'nikhil'); | 
   
 
 | 
   
 
 
... but I'm guessing it's supposed to do something like this:
   
	| Code: | 
   
  
	--Fetching data from Cache Table
 
 
SET OutputRoot.XMLNS.TCPSEND.TCP[] =
 
    SELECT T.TERMNO, T.portno
 
    FROM CacheQueueTable.DestinationData[] AS T;
 
 | 
   
 
 | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | smdavies99 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 3:16 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		    Jedi Council
 
 Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land. 
  | 
		  
		    
			  
				In my example, the procedure 'get_terminal' just returns an integer with a predefined range.
 
 
 For example, if the range was 1-3
 
 
Call 1 returns 1
 
Call 2 returns 2
 
Call 3 returns 3
 
Call 4 returns 1
 
etc etc etc
 
 
By calculating this in an Atomic Block, you can be certain that there will never be more than one flow or instance of a flow accessing the code inside the block at any one time
 
 
I stored the value in a normal shared ESQL variable. It was only ever accessed from within the procedure. 
 
Im my real system, I had and extra param (called Mode) in the procedure call. This was to allow a flow to actually set/change the range dynamically. All the flows/instances that read the next number called it with Mode = 0. To set it, I called it with Mode = 1.
 
You may node need this facility... 
 
 
The variable was declared as follows:-
 
 
DECLARE Next_Terminal shared INTEGER 0;
 
DECLARE Max_Terminal shared INTEGER 5;
 
 
IN the procedure
 
 
[code]
 
 CREATE PROCEDURE Get_Terminal(IN Mode Integer, OUT Terminal_no Integer)
 
 Begin
 
   BEGIN ATOMIC
 
      IF Mode = 0 THEN
 
         IF Next_Terminal = Max_Terminal 
 
            THEN
 
               set Next_Terminal = 1;
 
           ELSE
 
               set Next_Terminal = Next_Terminal + 1;
 
         END If;
 
        set Terminal_no = Next_Terminal;
 
  END;
 
 END;
 
[/code] _________________ WMQ User since 1999
 
MQSI/WBI/WMB/'Thingy' User since 2002
 
Linux user since 1995
 
 
 
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 4:14 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				hi got the point on how to do it and davies u are absolutely right and i tested your code and its working fine. i made a test example and it worked ....thanks ....
 
 
but 1 problem is still there that how to fetch data from in-memory cache table
 
 
i set the table in cache ..esql below 
 
 
IF CacheQueueTable.valid IS NULL THEN
 
		 		SET  CacheQueueTable.DestinationData[] = (Select emp.email as TERMNO,emp.name as portno from Database.EMP_DETAILS as emp WHERE emp.hostname = chardata);
 
		 		
 
		  SET CacheQueueTable.valid = true;
 
		END IF;	
 
 
 
And I fetch the Data from cache table ....esql below
 
 
SET  Environment.Variables.TCPSEND.TCP[] = (Select emp.email as TERMNO,emp.name as portno from CacheQueueTable.DestinationData[] as emp WHERE emp.hostname = chardata);
 
		SET  terminalnumber = Environment.Variables.TCPSEND.TCP[1].TERMNO;
 
		set portnumber = Environment.Variables.TCPSEND.TCP[1].portno;
 
 
 
i dnt know whether this is the way to access the data from cache table...
 
Here i am not able to get the values for terminalnumber and portnumber....
 
 
please help and thanks for your other code .... | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 5:35 am    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				hi 
 
 
tried a lot to get data from the cache table but it doesnt return data in environment variable array...
 
 
do any1 know how to get the data from cache table.... | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rekarm01 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 2:03 pm    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Grand Master
 
 Joined: 25 Jun 2008 Posts: 1415
  
  | 
		  
		    
			  
				
   
	| rohank84 wrote: | 
   
  
	| do any1 know how to get the data from cache table.... | 
   
 
 
Like this?
   
	| Code: | 
   
  
	SET terminalnumber = CacheQueueTable.DestinationData[1].TERMNO;
 
SET portnumber = CacheQueueTable.DestinationData[1].portno; | 
   
 
 | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | rohank84 | 
		  
		    
			  
				 Posted: Wed Jan 28, 2009 10:06 pm    Post subject:  | 
				     | 
			   
			 
		   | 
		
		
		   Centurion
 
 Joined: 31 Dec 2008 Posts: 109
  
  | 
		  
		    
			  
				hi rekarm01
 
 
your code is absolutely correct and it worked ....thanks 
 
 
but in my case i have to fire a query in cache table to get the result as the input will be different everytime. I tried to do this 
 
 
SET  terminalnumber = (Select emp.email as TERMNO from CacheQueueTable.DestinationData[] as emp WHERE emp.hostname = chardata);
 
 
		SET  portnumber = (Select emp.name as portno from CacheQueueTable.DestinationData[] as emp WHERE emp.hostname = chardata);
 
 
but its gives me an error 
 
 
BIP2497E: (.MF_TCP_SEND_Compute.Main, 26.  : Illegal data type for target. A list field reference is required. 
 
 
so there will be different data everytime coming from this query everytime
 
 
So is there anyway to get the data from cache table | 
			   
			 
		   | 
		
		
		  | Back to top | 
		  
		  	
		   | 
		
		
		    | 
		
		
		  | 
		    
		   |