Roberto Ostinelli 3 лет назад
Родитель
Сommit
1cffe1e317
3 измененных файлов с 131 добавлено и 0 удалено
  1. 34 0
      src/syn.erl
  2. 31 0
      test/syn_registry_SUITE.erl
  3. 66 0
      test/syn_test_gen_server.erl

+ 34 - 0
src/syn.erl

@@ -32,6 +32,8 @@
 -export([register/2, register/3, register/4]).
 -export([unregister/1, unregister/2]).
 -export([registry_count/1, registry_count/2]).
+%% gen_server via interface
+-export([register_name/2, unregister_name/1, whereis_name/1, send/2]).
 
 %% ===================================================================
 %% API
@@ -96,3 +98,35 @@ registry_count(Scope) ->
 -spec registry_count(Scope :: atom(), Node :: node()) -> non_neg_integer().
 registry_count(Scope, Node) ->
     syn_registry:count(Scope, Node).
+
+%% ----- \/ gen_server via module interface --------------------------
+-spec register_name(Name :: any(), Pid :: pid()) -> yes | no.
+register_name(Name, Pid) ->
+    case syn_registry:register(Name, Pid) of
+        ok -> yes;
+        _ -> no
+    end.
+
+-spec unregister_name(Name :: any()) -> any().
+unregister_name(Name) ->
+    case syn_registry:unregister(Name) of
+        ok -> Name;
+        _ -> nil
+    end.
+
+-spec whereis_name(Name :: any()) -> pid() | undefined.
+whereis_name(Name) ->
+    case syn_registry:lookup(Name) of
+        {Pid, Meta} -> Pid;
+        undefined -> undefined
+    end.
+
+-spec send(Name :: any(), Message :: any()) -> pid().
+send(Name, Message) ->
+    case whereis_name(Name) of
+        undefined ->
+            {badarg, {Name, Message}};
+        Pid ->
+            Pid ! Message,
+            Pid
+    end.

+ 31 - 0
test/syn_registry_SUITE.erl

@@ -33,6 +33,9 @@
 
 %% tests
 -export([
+    one_node_via_register_unregister/1
+]).
+-export([
     three_nodes_discover_default_scope/1,
     three_nodes_discover_custom_scope/1,
     three_nodes_register_unregister_and_monitor_default_scope/1,
@@ -59,6 +62,7 @@
 %% -------------------------------------------------------------------
 all() ->
     [
+        {group, one_process_registration},
         {group, three_nodes_process_registration}
     ].
 
@@ -76,6 +80,9 @@ all() ->
 %% -------------------------------------------------------------------
 groups() ->
     [
+        {one_process_registration, [shuffle], [
+            one_node_via_register_unregister
+        ]},
         {three_nodes_process_registration, [shuffle], [
             three_nodes_discover_default_scope,
             three_nodes_discover_custom_scope,
@@ -175,6 +182,30 @@ end_per_testcase(_, _Config) ->
 %% ===================================================================
 %% Tests
 %% ===================================================================
+one_node_via_register_unregister(_Config) ->
+    %% start syn
+    ok = syn:start(),
+    %% start gen server via syn
+    {ok, Pid} = syn_test_gen_server:start_link(),
+    %% retrieve
+    {Pid, undefined} = syn:lookup(syn_test_gen_server),
+    %% call
+    pong = syn_test_gen_server:ping(),
+    %% send via syn
+    syn:send(syn_test_gen_server, {self(), send_ping}),
+    syn_test_suite_helper:assert_received_messages([
+        reply_pong
+    ]),
+    %% stop server
+    syn_test_gen_server:stop(),
+    %% retrieve
+    syn_test_suite_helper:assert_wait(
+        undefined,
+        fun() -> syn:lookup(syn_test_gen_server) end
+    ),
+    %% send via syn
+    {badarg, {syn_test_gen_server, anything}} = catch syn:send(syn_test_gen_server, anything).
+
 three_nodes_discover_default_scope(Config) ->
     %% get slaves
     SlaveNode1 = proplists:get_value(slave_node_1, Config),

+ 66 - 0
test/syn_test_gen_server.erl

@@ -0,0 +1,66 @@
+%% ==========================================================================================================
+%% Syn - A global Process Registry and Process Group manager.
+%%
+%% The MIT License (MIT)
+%%
+%% Copyright (c) 2015-2021 Roberto Ostinelli <roberto@ostinelli.net> and Neato Robotics, Inc.
+%%
+%% Permission is hereby granted, free of charge, to any person obtaining a copy
+%% of this software and associated documentation files (the "Software"), to deal
+%% in the Software without restriction, including without limitation the rights
+%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+%% copies of the Software, and to permit persons to whom the Software is
+%% furnished to do so, subject to the following conditions:
+%%
+%% The above copyright notice and this permission notice shall be included in
+%% all copies or substantial portions of the Software.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+%% THE SOFTWARE.
+%% ==========================================================================================================
+-module(syn_test_gen_server).
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0]).
+-export([ping/0]).
+-export([stop/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
+
+start_link() ->
+    gen_server:start_link({via, syn, ?MODULE}, ?MODULE, [], []).
+
+ping() ->
+    gen_server:call({via, syn, ?MODULE}, ping).
+
+stop() ->
+    gen_server:cast({via, syn, ?MODULE}, stop).
+
+init(State) ->
+    {ok, State}.
+
+handle_call(ping, _From, State) ->
+    {reply, pong, State}.
+
+handle_cast(stop, State) ->
+    {stop, normal, State};
+
+handle_cast(_Msg, State) ->
+    {noreply, State}.
+
+handle_info({SenderPid, send_ping}, State) ->
+    SenderPid ! reply_pong,
+    {noreply, State}.
+
+terminate(_Reason, _State) ->
+    ok.
+
+code_change(_OldVsn, State, _Extra) ->
+    {ok, State}.