Change send/2 so that it returns the pid or pids the message was sent to #34

Closed
wants to merge 1 commit into
from

2 participants

@jcomellas

To use gproc to register names using the via mechanism that was
recently added to OTP (gen_server, gen_fsm, gen_event) it must provide a
send/2 function that can be used to implement the function with the following type spec:

send(Name :: term(), Msg :: term()) -> pid().

Currently gproc:send/2 returns the message that was sent. This patch
changes it so that the new type spec for it is:

send(Name :: term(), Msg :: term()) -> pid() | [pid()].

It will now return the pid or list of pids the message was sent to.

I know this is a backward incompatible change, so I will send another pull request in a few minutes that will add a new function called send_to_name/2 instead of changing send/2.

@jcomellas jcomellas Change send/2 so that it returns the pid or pids the message was sent to
To use gproc to register names using the 'via' mechanism that was
recently added to OTP (gen_server, gen_fsm, gen_event) it must provide a
send/2 function with the following type spec:

    send(Name :: term(), Msg :: term()) -> pid().

Currently gproc:send/2 returns the message that was sent. This patch
changes it so that the new type spec for it is:

   send(Name :: term(), Msg :: term()) -> pid() | [pid()].

It will now return the pid or list of pids the message was sent to.
2814eae
@jcomellas

I'd prefer this patch to go in instead of the one I sent afterwards, as it would allow gproc to be used as a drop-in name registry with OTP.

@uwiger
Owner

It is true that global:send/2 -> pid(), but the OTP behaviors all ignore the return value of Mod:send/2 (even wrap it inside a catch).

The most backward compatible change would therefore be to change the OTP documentation.

The OTP documentation is fairly vague on the subject already:

The Module callback should export the functions register_name/2,
unregister_name/1, whereis_name/1 and send/2, which should
behave like the corresponding functions in global.

@jcomellas

I agree, and there should probably be a behaviour for OTP name registries.

Do you think the OTP team would be willing to make this change?

BTW, I see the return of the pids the message was sent to as something much more useful than the message that was sent. The caller already has the message and will probably never use that return value, whereas it might come in handy to know which processes received your message.

@uwiger
Owner

This is true, but returning a pid like global still wouldn't work, since gproc:send/2 can (in the case of using a property) send to several processes. The most useful return value then might be a list of all pids that were sent the message.

Returning the message itself of course mimicks the erlang send operator (!). In the case of !, this property can be use to write stuff like P1 ! P2 ! P3 ! P4 ! Msg.

Not that I imagine anyone ever does...

@jcomellas

If you look at the patch you'll see that if you send a message to multiple processes you'll actually receive the list of pids the message was sent to.

@uwiger
Owner

Well, yes, but the question then is whether there is sufficient justification for an API change.

@uwiger
Owner

I will close this issue, as the return value of gproc:send/2 is ignored by the OTP behaviors (even though it's not documented as such). OTP already has a 'conflict' as global:send(P,Msg) -> pid(), whereas erlang:send(P,Msg) -> Msg, and I'm reluctant to make an API change when the current API actually doesn't break anything (but actually changing it might).

Thanks for pointing out the issue with the {via, ...} construct, though. It should be clarified.

@uwiger uwiger closed this May 24, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment