Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the process dictionary appropriate in this case?

Tags:

erlang

I've read several comments here and elsewhere suggesting that Erlang's process dictionary was a bad idea and should die. Normally, as a total Erlang newbie, I'd just avoid it. However, in this situation my other options aren't great.

I have a main dispatcher function that looks something like this:

dispatch(State) ->
    receive
        {cmd1, Params} ->
            NewState = do_cmd1_stuff(Params, State),
            dispatch(NewState);
        {cmd2, Params} ->
            NewState = do_cmd2_stuff(Params, State),
            dispatch(NewState);
        BadMsg ->
            log_error(BadMsg),
            dispatch(State)
    end.

Obviously, my names are more meaningful to me, but that's the gist of it. Deep down in a function called by a function called by a function called by do_cmd2_stuff(), I want to send out messages to all my users telling them about something I've done. In order to do that, I need to get the list of users from the point where I send the messages. The user list doesn't lend itself easily to sticking in the global state, since that's just one data structure representing the only block of data on which I operate.

The way I see it, I have a couple unpleasant options other than using the process dictionary. I can send the user list through all the various levels of functions down to the very bottom one that does the broadcasting. That's unpleasant because it causes all my functions to gain a parameter, whether they really care about it or not.

Alternatively, I could have all the do_cmdN_stuff() functions return a message to send. That's not great either though, since sending the message may not be the last thing I want to do and it clutters up my dispatcher with a bunch of {Msg, NewState} tuples. Furthermore, some of the functions might not have any messages to send some of the time.

Like I said earlier, I'm very new to Erlang. Maybe someone with more experience can point me at a better way. Is there one? Is the process dictionary appropriate in this case?

like image 991
nmichaels Avatar asked Nov 01 '10 22:11

nmichaels


People also ask

What is the meaning of process in the dictionary?

noun [ C ] us. /ˈprɑs·es, ˈproʊ·ses/ a series of actions or events performed to make something or achieve a particular result, or a series of changes that happen naturally: Completing his degree at night was a long process.

What is appropriate word example?

adjective. suitable or fitting for a particular purpose, person, occasion, etc.: an appropriate example;an appropriate dress. belonging to or peculiar to a person; proper: Each played his appropriate part.

Is it appropriate to or appropriate for?

appropriate for (something) To designate for a specific purpose. In this usage, a noun or pronoun can be used between "appropriate" and "for." When "appropriate" is used as a verb, the last syllable is pronounced "ate." How much money was appropriated for education initiatives this quarter?

What does it mean to appropriate something?

: to set apart for or assign to a particular purpose or use.


2 Answers

The general rule is that if you have doubts, you shouldn't use the process dictionary.

If the two options you mentioned aren't good enough (I personally like the one where you return the messages to send) and what you want is some particular piece of code to track users and forward messages to them, maybe what you want to do is have a process holding that info.

Pid ! {forward, Msg}

where Pid will take care of sending everything to a bunch of other processes. Now, you would still need to pass the Pid around, unless you give it a name in some registry to find it. Either with register/2, global or gproc.

like image 146
I GIVE TERRIBLE ADVICE Avatar answered Oct 05 '22 04:10

I GIVE TERRIBLE ADVICE


A simple answer would be to nest your global within a state record, which is then threaded through the system, at least at the stop level. This makes it easy to add new fields to the state in the future, not an uncommon occurrence, and allow you to keep your global state data structure untouched. So initially

-record(state, {users=[],state_data}).

Defining it as a record makes it easy to access and extend when necessary.

like image 44
rvirding Avatar answered Oct 05 '22 02:10

rvirding