Browse Source

Pass metadata information to the callback on conflicting process function.

Roberto Ostinelli 9 years ago
parent
commit
9e16652169
3 changed files with 27 additions and 21 deletions
  1. 5 3
      README.md
  2. 13 10
      src/syn_consistency.erl
  3. 9 8
      test/syn_consistency_SUITE.erl

+ 5 - 3
README.md

@@ -233,20 +233,22 @@ If this is not desired, you can set the `conflicting_process_callback` option to
 
 The callback function is defined as:
 ```erlang
-CallbackFun = fun(Key, Pid) -> any().
+CallbackFun = fun(Key, Pid, Metadata) -> any().
 
 Types:
 	Key = any()
 	Pid = pid()
+	Metadata = any()
 ```
-The `Key` and `Pid` are the ones of the process that is to be discarded.
+The `Key`, `Pid` and `Metadata` are the ones of the process that is to be discarded.
 
 For instance, if you want to send a `shutdown` message to the discarded process:
 
 ```erlang
 -module(my_callback).
+-export([callback_on_conflicting_process/3]).
 
-callback_on_conflicting_process(_Key, Pid) ->
+callback_on_conflicting_process(_Key, Pid, _Metadata) ->
 	Pid ! shutdown
 ```
 

+ 13 - 10
src/syn_consistency.erl

@@ -181,7 +181,7 @@ automerge(RemoteNode, CallbackModule, CallbackFunction) ->
         fun() ->
             error_logger:warning_msg("AUTOMERGE starting for remote node ~s (global lock is set)", [RemoteNode]),
             check_stitch(RemoteNode, CallbackModule, CallbackFunction),
-            error_logger:warning_msg("AUTOMERGE done (global is about to be unset)")
+            error_logger:warning_msg("AUTOMERGE done (global lock is about to be unset)")
         end).
 
 -spec check_stitch(RemoteNode :: atom(), CallbackModule :: atom(), CallbackFunction :: atom()) -> ok.
@@ -243,10 +243,10 @@ purge_double_processes_from_local_node(LocalProcessesInfo, RemoteProcessesInfo,
     ets:insert(Tab, LocalProcessesInfo),
 
     %% find doubles
-    F = fun({Key, _RemoteProcessPid}) ->
+    F = fun({Key, _RemoteProcessPid, _RemoteProcessMeta}) ->
         case ets:lookup(Tab, Key) of
             [] -> ok;
-            [{Key, LocalProcessPid}] ->
+            [{Key, LocalProcessPid, LocalProcessMeta}] ->
                 %% remove it from local mnesia table
                 mnesia:dirty_delete(syn_processes_table, Key),
                 %% remove it from ETS
@@ -256,9 +256,11 @@ purge_double_processes_from_local_node(LocalProcessesInfo, RemoteProcessesInfo,
                     undefined ->
                         error_logger:warning_msg("Found a double process for ~s, killing it on local node ~p", [Key, node()]),
                         exit(LocalProcessPid, kill);
-                    _ -> spawn(fun() ->
-                        error_logger:warning_msg("Found a double process for ~s, about to trigger callback on local node ~p", [Key, node()]),
-                        CallbackModule:CallbackFunction(Key, LocalProcessPid) end)
+                    _ -> spawn(
+                        fun() ->
+                            error_logger:warning_msg("Found a double process for ~s, about to trigger callback on local node ~p", [Key, node()]),
+                            CallbackModule:CallbackFunction(Key, LocalProcessPid, LocalProcessMeta)
+                        end)
                 end
         end
     end,
@@ -282,19 +284,20 @@ write_local_processes_to_remote(RemoteNode, LocalProcessesInfo) ->
 -spec get_processes_info_of_node(Node :: atom()) -> list().
 get_processes_info_of_node(Node) ->
     %% build match specs
-    MatchHead = #syn_processes_table{key = '$1', pid = '$2', node = '$3'},
+    MatchHead = #syn_processes_table{key = '$1', pid = '$2', node = '$3', meta = '$4'},
     Guard = {'=:=', '$3', Node},
-    ProcessInfoFormat = {{'$1', '$2'}},
+    ProcessInfoFormat = {{'$1', '$2', '$4'}},
     %% select
     mnesia:dirty_select(syn_processes_table, [{MatchHead, [Guard], [ProcessInfoFormat]}]).
 
 -spec write_processes_info_to_node(Node :: atom(), ProcessesInfo :: list()) -> ok.
 write_processes_info_to_node(Node, ProcessesInfo) ->
-    FWrite = fun({Key, ProcessPid}) ->
+    FWrite = fun({Key, ProcessPid, ProcessMeta}) ->
         mnesia:dirty_write(#syn_processes_table{
             key = Key,
             pid = ProcessPid,
-            node = Node
+            node = Node,
+            meta = ProcessMeta
         })
     end,
     lists:foreach(FWrite, ProcessesInfo).

+ 9 - 8
test/syn_consistency_SUITE.erl

@@ -46,7 +46,7 @@
 
 %% internal
 -export([process_reply_main/0]).
--export([conflicting_process_callback_dummy/2]).
+-export([conflicting_process_callback_dummy/3]).
 
 %% include
 -include_lib("common_test/include/ct.hrl").
@@ -345,7 +345,8 @@ two_nodes_netsplit_callback_resolution_when_there_are_conflicts(Config) ->
     global:register_name(syn_consistency_SUITE_result, ResultPid),
 
     %% register
-    ok = syn:register(conflicting_key, SlavePid),
+    Meta = {some, meta, data},
+    ok = syn:register(conflicting_key, SlavePid, Meta),
     timer:sleep(100),
 
     %% check tables
@@ -364,7 +365,7 @@ two_nodes_netsplit_callback_resolution_when_there_are_conflicts(Config) ->
     [CurrentNode] = mnesia:table_info(syn_processes_table, active_replicas),
 
     %% now register the local pid with the same key
-    ok = syn:register(conflicting_key, LocalPid),
+    ok = syn:register(conflicting_key, LocalPid, Meta),
 
     %% check process
     LocalPid = syn:find_by_key(conflicting_key),
@@ -384,7 +385,7 @@ two_nodes_netsplit_callback_resolution_when_there_are_conflicts(Config) ->
     %% check message received from killed pid
     KilledPid = lists:nth(1, lists:delete(FoundPid, [LocalPid, SlavePid])),
     receive
-        {exited, KilledPid} -> ok
+        {exited, KilledPid, Meta} -> ok
     after 2000 ->
         ok = conflicting_process_did_not_receive_message
     end,
@@ -471,10 +472,10 @@ three_nodes_netsplit_kill_resolution_when_there_are_conflicts(Config) ->
 %% ===================================================================
 process_reply_main() ->
     receive
-        shutdown ->
+        {shutdown, Meta} ->
             timer:sleep(500), %% wait for global processes to propagate
-            global:send(syn_consistency_SUITE_result, {exited, self()})
+            global:send(syn_consistency_SUITE_result, {exited, self(), Meta})
     end.
 
-conflicting_process_callback_dummy(_Key, Pid) ->
-    Pid ! shutdown.
+conflicting_process_callback_dummy(_Key, Pid, Meta) ->
+    Pid ! {shutdown, Meta}.