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 |
|
 |
|