|
|
| Author |
Message |
|
| chagan |
Posted: Sat Apr 04, 2009 5:02 am |
|
|
|
Joined: 04 Apr 2009
Posts: 3
|
Perhaps one of you experts can explain something to me?
The chat app I'm building starts a gen_server on every client, and a different gen_server on the main server, which is responsible for long term persistence and also for filling in content for absent users (present users distribute their own content and history on request).
Every example I see is structured like this (snippet, obviously):
-export([handle_call/3,etc]).
-export([my_function/1]).
handle_call({my_function,_SomeArgs},_From,State)->
%%Do the actual work here
State.
my_function(SomeArgs)->
gen_server:call(?SERVER, {my_function,SomeArgs}).
My question is, what is the benefit of explicitly exporting my_function, which is a wrapper to the functionality exposed by calling the gen_server? The server can be accessed from other nodes with gen_server:call(GlobalNameForThisServer,{my_function,SomeArgs}) anyway.
Is there some nuance to this indirection that enables hotswapping or something like that? Why double up the declarations like this?
I look forward to being instructed as to why this redundancy is the norm in such a concise and beautiful language. |
|
|
| Back to top |
|
| mhenoch |
Posted: Tue Apr 07, 2009 2:15 pm |
|
|
|
User
Joined: 06 Nov 2008
Posts: 29
|
You use the wrapper functions so that other parts of the code do not need to know the internals of the module.
For example, you might at some point decide that the thing that this function does should be done in the process of the caller, not in the gen_server. Or you might decide to use a gen_fsm instead of a gen_server, or you might decide to have several gen_servers, sending requests to a certain server depending on the arguments, etc. If all calls from other modules go through the wrapper functions, the other modules do not need to be changed at all.
Besides, foo:my_function(bar) is shorter than gen_server:call(foo, {my_function, bar})  |
|
|
| Back to top |
|
| chagan |
Posted: Wed Apr 08, 2009 1:36 am |
|
|
|
Joined: 04 Apr 2009
Posts: 3
|
Thanks for your answer, mhenoch. I understand what you mean about hardening the interfaces so that internal changes can take place without other clients needing to adapt.
How would you easily register all the other nodes in the network so that they're addressable in the style of
foo:my_thing(Args)?
I've been trawling through the global module and haven't got a clear picture of how to do it. Say you had fifteen users, each of whom had globally registered themselves with their nickname (by initializing their server with {global,Nick}, and user Foo wanted to call app:message(Msg) on user Bar? |
|
|
| Back to top |
|
| chagan |
Posted: Wed Apr 08, 2009 1:49 am |
|
|
|
Joined: 04 Apr 2009
Posts: 3
|
Oops, missed a closing bracket after {global, Nick}. No wonder my answer wouldn't compile  |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
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 You can attach files in this forum You can download files in this forum
|
|
|