broadcast message to all gen_server

classic Classic list List threaded Threaded
6 messages Options
AD
Reply | Threaded
Open this post in threaded view
|

broadcast message to all gen_server

AD
Hey All,

 I have a situation where i am trying to handle a case where I am using
sockjs and need to send a message to each sockjs session_server (which is a
gen_server).  I am using gproc() but I cant simply do a gproc_send() b/c
the message ends up in handle_info() instead of properly in handle_call().
 I have managed to work this out, when receiving a message from rabbitmq i
do a gproc:lookup_pids() and then loop through each pid and do a
gen_server:call(PID,Message).  The issue is this is a linear process, is
there a way to handle sending gen_server:call() to all the processes
concurrently ?

 One way i thought of doing this is having a lightweight set of "listener"
processes each mapped to a socjks session process and then use gproc() to
broadcast to the lightweight process which would in turn send a
gen_server:call().

Any thoughts?

Thanks
-AD
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120410/0e27aee4/attachment.html>

Reply | Threaded
Open this post in threaded view
|

broadcast message to all gen_server

Samuel Elliott
Why can't you do it in handle_info ? That still has access to modify
the state and do everything a :call does, except maybe reply, however
if you're sending the message from somewhere else, you could just
reply with normal erlang message passing.

Another option is the following: write a function that calls a given
gen_server with what you want it to, then go through your list of
gen_servers using a list comprehension and spawn that function with
the server to run. That said, this is also a fire-and-forget way of
doing it, unless after you call the gen server, you send a message
back to the spawning process to confirm it worked. Something like the
following:

call_servers(Servers, Message, Timeout) ->
  [spawn(?MODULE, call_server, [GServer, self() Message]) || GServer
<- Servers ],
  wait_loop(Servers, Timeout).

call_server(GServer, Master, Message) ->
  gen_server:call(GServer, Message),
  Master ! {done, GServer}.

wait_loop(Servers, Timeout) ->
  receive
    {done, GServer} when lists:member(GServer, Server) ->
      Servers1 = lists:delete(GServer, Servers),
      case Servers1 of
        [] -> ok;
        _ -> wait_loop(Servers1, Timeout)
      end;
  after
    Timeout ->
      never_finished
  end.

Note: Timeout is the maximum time to wait between gen_server:calls,
not the maximum time to wait for them all. that would be more complex,
but might be what you need.

Sam

On Tue, Apr 10, 2012 at 8:37 PM, AD <straightflush> wrote:

> Hey All,
>
> ?I have a situation where i am trying to handle a case where I am using
> sockjs and need to send a message to each sockjs session_server (which is a
> gen_server). ?I am using gproc() but I cant simply do a gproc_send() b/c the
> message ends up in handle_info() instead of properly in handle_call(). ?I
> have managed to work this out, when receiving a message from rabbitmq i do a
> gproc:lookup_pids() and then loop through each pid and do a
> gen_server:call(PID,Message). ?The issue is this is a linear process, is
> there a way to handle sending gen_server:call() to all the processes
> concurrently ?
>
> ?One way i thought of doing this is having a lightweight set of "listener"
> processes each mapped to a socjks session process and then use gproc() to
> broadcast to the lightweight process which would in turn send a
> gen_server:call().
>
> Any thoughts?
>
> Thanks
> -AD
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions
> http://erlang.org/mailman/listinfo/erlang-questions
>



--
Samuel Elliott
sam
http://lenary.co.uk/
+44 (0)7891 993 664


Reply | Threaded
Open this post in threaded view
|

broadcast message to all gen_server

Tilman Holschuh
In reply to this post by AD

On 12-04-10 12:37 PM, AD wrote:
>   I have a situation where i am trying to handle a case where I am using
> sockjs and need to send a message to each sockjs session_server (which is a
> gen_server).  I am using gproc() but I cant simply do a gproc_send() b/c
> the message ends up in handle_info() instead of properly in handle_call().
>   I have managed to work this out, when receiving a message from rabbitmq i
> do a gproc:lookup_pids() and then loop through each pid and do a
> gen_server:call(PID,Message).  The issue is this is a linear process, is
> there a way to handle sending gen_server:call() to all the processes
> concurrently ?

Do you need a response from the gen_server:call? If not you could just
use a cast instead. Something like:

[gen_server:cast(Pid, Message) || Pid <- gproc:lookup_pids()]


Cheers
- Tilman


AD
Reply | Threaded
Open this post in threaded view
|

broadcast message to all gen_server

AD
the gen_server is part of the sockjs server and i was trying to not
modify/fork his code and leverage what is already there. Currently he uses
a handle_call() so was looking at handling it outside his code.

-AD

On Tue, Apr 10, 2012 at 4:18 PM, Tilman Holschuh
<tilman.holschuh>wrote:

>
> On 12-04-10 12:37 PM, AD wrote:
>
>>  I have a situation where i am trying to handle a case where I am using
>> sockjs and need to send a message to each sockjs session_server (which is
>> a
>> gen_server).  I am using gproc() but I cant simply do a gproc_send() b/c
>> the message ends up in handle_info() instead of properly in handle_call().
>>  I have managed to work this out, when receiving a message from rabbitmq i
>> do a gproc:lookup_pids() and then loop through each pid and do a
>> gen_server:call(PID,Message).  The issue is this is a linear process, is
>> there a way to handle sending gen_server:call() to all the processes
>> concurrently ?
>>
>
> Do you need a response from the gen_server:call? If not you could just use
> a cast instead. Something like:
>
> [gen_server:cast(Pid, Message) || Pid <- gproc:lookup_pids()]
>
>
> Cheers
> - Tilman
>
> ______________________________**_________________
> erlang-questions mailing list
> erlang-questions
> http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120410/0fff1f9c/attachment.html>

Reply | Threaded
Open this post in threaded view
|

broadcast message to all gen_server

Tilman Holschuh
And this doesn't work for you?

https://github.com/sockjs/sockjs-erlang/blob/master/src/sockjs_session.erl#L66

It's a cast and you can supply the pid (just wondering why he explicitly
returns ok but that doesn't matter).

Cheers
- Tilman

On 12-04-10 03:01 PM, AD wrote:

> the gen_server is part of the sockjs server and i was trying to not
> modify/fork his code and leverage what is already there. Currently he uses
> a handle_call() so was looking at handling it outside his code.
>
> -AD
>
> On Tue, Apr 10, 2012 at 4:18 PM, Tilman Holschuh
> <tilman.holschuh>wrote:
>
>>
>> On 12-04-10 12:37 PM, AD wrote:
>>
>>>   I have a situation where i am trying to handle a case where I am using
>>> sockjs and need to send a message to each sockjs session_server (which is
>>> a
>>> gen_server).  I am using gproc() but I cant simply do a gproc_send() b/c
>>> the message ends up in handle_info() instead of properly in handle_call().
>>>   I have managed to work this out, when receiving a message from rabbitmq i
>>> do a gproc:lookup_pids() and then loop through each pid and do a
>>> gen_server:call(PID,Message).  The issue is this is a linear process, is
>>> there a way to handle sending gen_server:call() to all the processes
>>> concurrently ?
>>>
>>
>> Do you need a response from the gen_server:call? If not you could just use
>> a cast instead. Something like:
>>
>> [gen_server:cast(Pid, Message) || Pid<- gproc:lookup_pids()]
>>
>>
>> Cheers
>> - Tilman
>>
>> ______________________________**_________________
>> erlang-questions mailing list
>> erlang-questions
>> http://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>>
>


AD
Reply | Threaded
Open this post in threaded view
|

broadcast message to all gen_server

AD
yea i finally backtracked more through the code and realized you can just do

 sockjs_session:send(iolist_to_binary([Msg]),{sockjs_session,{P,empty}})

 as an API call to a gen_server:cast() call.  I am gonna throw this into a
spawn(fun() -> ) to get as close to "broadcast" as possible unless there is
negligible gain in doing this since its an async call anyway.

-A



On Tue, Apr 10, 2012 at 7:09 PM, Tilman Holschuh
<tilman.holschuh>wrote:

> And this doesn't work for you?
>
> https://github.com/sockjs/**sockjs-erlang/blob/master/src/**
> sockjs_session.erl#L66<https://github.com/sockjs/sockjs-erlang/blob/master/src/sockjs_session.erl#L66>
>
> It's a cast and you can supply the pid (just wondering why he explicitly
> returns ok but that doesn't matter).
>
> Cheers
> - Tilman
>
>
> On 12-04-10 03:01 PM, AD wrote:
>
>> the gen_server is part of the sockjs server and i was trying to not
>> modify/fork his code and leverage what is already there. Currently he uses
>> a handle_call() so was looking at handling it outside his code.
>>
>> -AD
>>
>> On Tue, Apr 10, 2012 at 4:18 PM, Tilman Holschuh
>> <tilman.holschuh>**wrote:
>>
>>
>>> On 12-04-10 12:37 PM, AD wrote:
>>>
>>>   I have a situation where i am trying to handle a case where I am using
>>>> sockjs and need to send a message to each sockjs session_server (which
>>>> is
>>>> a
>>>> gen_server).  I am using gproc() but I cant simply do a gproc_send() b/c
>>>> the message ends up in handle_info() instead of properly in
>>>> handle_call().
>>>>  I have managed to work this out, when receiving a message from
>>>> rabbitmq i
>>>> do a gproc:lookup_pids() and then loop through each pid and do a
>>>> gen_server:call(PID,Message).  The issue is this is a linear process, is
>>>> there a way to handle sending gen_server:call() to all the processes
>>>> concurrently ?
>>>>
>>>>
>>> Do you need a response from the gen_server:call? If not you could just
>>> use
>>> a cast instead. Something like:
>>>
>>> [gen_server:cast(Pid, Message) || Pid<- gproc:lookup_pids()]
>>>
>>>
>>> Cheers
>>> - Tilman
>>>
>>> ______________________________****_________________
>>> erlang-questions mailing list
>>> erlang-questions
>>> http://erlang.org/mailman/****listinfo/erlang-questions<http://erlang.org/mailman/**listinfo/erlang-questions>
>>> <http**://erlang.org/mailman/**listinfo/erlang-questions<http://erlang.org/mailman/listinfo/erlang-questions>
>>> >
>>>
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120410/e816d151/attachment.html>