Subscribing to callbacks twice?
vans163 opened this issue · comments
Should subscribing to the same group callbacks with the same function twice be not allowed?
cpg:add_join_callback("group", fun test_cpg_app:join_callback/2).
cpg:add_join_callback("group", fun test_cpg_app:join_callback/2).
cpg:join("group", self()).
% join_callback procs twice
Its easy to subscribe twice to the same callback if a subscribing process gets restarted by a supervisor.
Its better to not try to prevent the usage of the same function as a callback for the same group name. Instead, just call cpg:remove_join_callback in the terminate callback of the OTP behaviour (also, make sure the supervisor specifies the timeout for shutdown as an integer, not brutual_kill
, and use trap_exit in the init
callback to make the info
message {EXIT,...}
return {stop...}
so exceptions are handled).
Allowing the same callback to be used multiple times is similar to allowing the same process to have multiple join
s with the same group name, which is also allowed, and can change the probability of its selection (if other processes have also used join
). It is typical to use the same callback function with multiple group names, but it seems inappropriate to check whether the same function is a callback already for the same group name, since there is likely a use-case for that. Also, the check wouldn't be possible, if {Module, FunctionName}
was allowed as a callback function, which may be helpful in the future.
Makes sense and follows the promises cpg makes in relation to CAP.
It seems I missed a point in the first paragraph, I take that to mean if the process that did add_join_callback dies, the callback will be removed? In which case the same process after being restarted by a supervisor will not double subscribe.
And allowing the double subscription is because there is no consistent registry of what has which subscription.
@vans163 The callbacks are just for monitoring whether a join
/leave
occurs, and they are separate from the lifetime of the pid used for join
/leave
function calls. The callback function usage will remain until you remove it or the cpg scope process dies. The pid passed to join
will remain in a group until it is passed to the leave
function, or the pid dies, which means that a netsplit could make it temporarily disappear, though it can appear later with the same association. So, the callbacks for monitoring the occurrence of a join
/leave
really is separate from the actual join
/leave
function call usage, where the callbacks are just a method of having asynchronous notifications that describe the occurrence of a join
or leave
.