tags:

views:

108

answers:

2

Hi All,

I am building a network router application using Erlang OTP framework.

In its process of running a Supervisor creates two genservers and each estagen_server:call(CurrentProcName,{BinEvent,UniqueTrxId,MdPid},infinity),blishes a tcp connection to two individual servers.

Now while running the application , It happens that one genserver receives a duplicate event , on such a case I want that event to be processed by the second gen_server .

For this , i am calling gen_server:call(NextProcName,{BinEvent,UniqueTrxId,MdPid},infinity),

This function I am calling inside the gen_server module when the condition for duplicate event satisfies.

NextProcName :: It is the registered name for the second gen_server

NOTE :: the code remains the same for both gen_server's

The problem is I am able to duplicate events but the event is somehow not getting passed to the second gen_server :(

Please suggest If I am doing it in the wrong way or not.

+2  A: 

If you can share the source, it would be appreciated.

Are you sure the message is really received or do you just not receive an answer?

The most plausible problem I see here is that you're forwarding a message in a synchronous manner. If it's not the case, then you can disregard my post entirely. For now, let's see how synchronous forwarding plays out:

 client          server1             server2
   |                |                   |
   >--- Msg1 ----> (ok)                 |
(waits S1)          |                   | 
  (ok) <-- Reply ---<                   |
   >--- Msg2 ----> (ok)                 |
(waits S1)          >----- Msg2 -----> (ok)
(waits S1)      (waits S2) <--- Reply --<      
(waits S1)      (Waits S2)              |

          *Stuff crashes*

This is not exactly clear, but it shows what's going on. Here Server1 is basically still counting as processing the message Msg2 to the gen_server behaviour, and will thus never read the reply from Server2 that it is waiting for. This will usually end up in a timeout and crash.

The correct way to do this is to instead send an asynchronous call (a cast) from Server1 to Server2, including the From variable so thatServer2 can reply with gen_server:reply/2 to substitute itself to Server1. Server1 should then return with a noreply tuple. This will free Server1's process and it'll be able to keep on processing other stuff.

I GIVE TERRIBLE ADVICE
You surely dont give terrible advice :P.
arn_ml
I am really sorry that I cannot share the code at this point of time. But I will try My level best to explain the conditions as an answer in this thread instead of a comment.
arn_ml
A: 

Switch --->one event ----> spawn a client----> Server 1 | --->sec.event ----> spawn a client----> Server 2 | --->third event---> spawn a client----> Server 1 | --->fourth event--> spawn a client----> Server 2

1> The switch will make a tcp connection with the erlang listener process.

2> This listener process will spawn a client process for each event.

3> This Client process after doing some processing on the event, send's the event to Server 1 or Server 2 in alternative manner.

Note:: I am using gen_server:call request. Will it affe ct the performance

4> The Server(1 or 2) which is a gen_server manages all the connections with the backend server's to which the events are sent which it receives from client.

5> After the client gets the response from server it sends it back to the switch and exits.

6> In case the any of the gen_server gets duplicate event it will send to another gen_server using gen_call.

So I have basically two questions : 1> Client calling gen_server:call to gen_server to forward event.Client needs to get the response event back from gen_server. which it will give it back to Switch 2> gen_server calling another gen_server by gen_server:call in case of duplicate event.

Right Now , for fairly high load i am getting loads of timed out messages as each client process waits for reply (using receive) and gets timed out (specified by after statement)

arn_ml
Can I use gen_server:cast to increase the performance ?
arn_ml
If you're putting `receive` statements inside of a gen_server callback function, you're doing something wrong. The handling of messages in a process' mailbox is done by the gen_server behaviour itself, not by you.
I GIVE TERRIBLE ADVICE
I am using receive statement in the client process not in the gen server. The gen server receives resonse from the backend servers using handle_info call back.
arn_ml
For me the internal working of gen_server is still a mystery
arn_ml
I have been going through this tutorial on building non-blocking erlang server http://www.trapexit.org/Building_Non_Blocking_Erlang_apps
arn_ml
But I am unable to make this working.. the handle info call receives the response from backend server but I am unable to send that response back to the worker process using gen_server:reply call
arn_ml
And it starts working when I make the handle_call return as {reply,ok,State} instead of {noreply,State} as mentioned in the tutorial. Also my worker process is using receive statement to get the response back from the gen+_server:reply used in handle_call.Please help :(
arn_ml