Sergey
Sergey

Reputation: 155

Erlang: how to use gproc

I am a little confused with gproc and Pub/Sub methods( https://github.com/uwiger/gproc#use-case-pubsub-patterns ). I can't understand how to receive messages from another process.

Example:

    -module(ws_handler).
    -export([init/2]). 

 init(Req, Opts) ->
    lager:info("WS: init ws handler"),
    gproc:reg({p, l, {?MODULE, WSNewMsgKey}}),
    {cowboy_websocket, Req, Opts}.

 process_data(Data) ->
    lager:info("WS: start processing of json data"),
    gproc:send({p, l, WSNewMsgKey}, {self(), WSNewMsgKey, Data}).

There are 2 processes, both of them are registered as subscribers. They should share incoming data with each other. I guess that i have to implement some interface/function but docs don't tell which exactly.

Upvotes: 0

Views: 1912

Answers (1)

zxq9
zxq9

Reputation: 13154

I've never used gproc for this, but it certainly seems like two things are missing: a definition of WSNewMsgKey (its never in scope in your snippet above) and a receive clause somewhere to accept the messages sent:

-module(ws_handler).
-export([init/2]). 

init(Req, Opts) ->
    gproc:reg({p, l, {?MODULE, ws_event}}),
    {some_state_blah, Req, Opts}.

notify_peers(Event) ->
    gproc:send({p, l, ws_event}, {self(), ws_event, Event}).

...and elsewhere either

handle_info({From, ws_event, Event}, State) ->
    ok = handle_ws_event(From, Event).

or in your loop (if you wrote your process by hand):

loop(State) ->
  receive
    {From, ws_event, Event} ->
        ok = handle_ws_event(From, Event),
        loop(State);
    Whatever ->
        % other stuff...
  end.

I'm not sure if the message that is sent would be sent by as a call, a cast, or a normal message (I'm assuming either an OTP generic cast, or normal message) -- but it seems that this is what should happen. In all cases, though, you need a well-defined key to identify the category of message being sent, and here I've used the atom 'ws_event' to make this explicit.

As for the details of the snippet above... you appear to be broadcasting the same JSON message to a bunch of processes at once for some sort of processing? I'm not sure what this would do for you -- I can't think of any case where broadcasting raw JSON would be beneficial (unless maybe if the need is to broadcast the JSON outside of the system and you are broadcasting to a bunch of subscribed client socket handlers?). So I'm confused at the context (what are you trying to achieve?).

This appears to be the way the docs intend this to be used -- but I'd have to actually play with it to be certain.

Upvotes: 1

Related Questions