capricorn 0.2.25 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. data/LICENSE +19 -0
  2. data/README.md +1 -0
  3. data/bin/capricorn-app-scaffolder +27 -0
  4. data/bin/capricorn-gem-spec +33 -0
  5. data/bin/capricornctl +12 -0
  6. data/bin/capricornd +31 -0
  7. data/erlang/lib/bert/doc/overview.edoc +4 -0
  8. data/erlang/lib/bert/ebin/bert.app +9 -0
  9. data/erlang/lib/bert/rebar.config +3 -0
  10. data/erlang/lib/bert/src/bert.erl +69 -0
  11. data/erlang/lib/bertio/doc/overview.edoc +4 -0
  12. data/erlang/lib/bertio/ebin/bertio.app +9 -0
  13. data/erlang/lib/bertio/rebar.config +3 -0
  14. data/erlang/lib/bertio/src/bertio.erl +28 -0
  15. data/erlang/lib/bertrpc/doc/overview.edoc +4 -0
  16. data/erlang/lib/bertrpc/ebin/bertrpc.app +12 -0
  17. data/erlang/lib/bertrpc/include/bertrpc.hrl +1 -0
  18. data/erlang/lib/bertrpc/rebar.config +5 -0
  19. data/erlang/lib/bertrpc/src/bertrpc.erl +471 -0
  20. data/erlang/lib/bertrpc/src/bertrpc_hello_world.erl +148 -0
  21. data/erlang/lib/bertrpc/src/fd_tcp.erl +376 -0
  22. data/erlang/lib/capricorn/doc/overview.edoc +4 -0
  23. data/erlang/lib/capricorn/ebin/capricorn.app +56 -0
  24. data/erlang/lib/capricorn/include/capricorn.hrl +76 -0
  25. data/erlang/lib/capricorn/rebar.config +3 -0
  26. data/erlang/lib/capricorn/src/cap_application.erl +170 -0
  27. data/erlang/lib/capricorn/src/cap_cluster.erl +121 -0
  28. data/erlang/lib/capricorn/src/cap_cluster_gems.erl +422 -0
  29. data/erlang/lib/capricorn/src/cap_config.erl +25 -0
  30. data/erlang/lib/capricorn/src/cap_dets_updater.erl +26 -0
  31. data/erlang/lib/capricorn/src/cap_event_sup.erl +35 -0
  32. data/erlang/lib/capricorn/src/cap_events.erl +24 -0
  33. data/erlang/lib/capricorn/src/cap_external_api.erl +87 -0
  34. data/erlang/lib/capricorn/src/cap_external_apps_api.erl +125 -0
  35. data/erlang/lib/capricorn/src/cap_external_gems_api.erl +85 -0
  36. data/erlang/lib/capricorn/src/cap_external_machines_api.erl +18 -0
  37. data/erlang/lib/capricorn/src/cap_gem_utils.erl +111 -0
  38. data/erlang/lib/capricorn/src/cap_internal_api.erl +69 -0
  39. data/erlang/lib/capricorn/src/cap_internal_apps_api.erl +38 -0
  40. data/erlang/lib/capricorn/src/cap_log.erl +113 -0
  41. data/erlang/lib/capricorn/src/cap_machine.erl +338 -0
  42. data/erlang/lib/capricorn/src/cap_machine_apps.erl +410 -0
  43. data/erlang/lib/capricorn/src/cap_machine_apps_sup.erl +57 -0
  44. data/erlang/lib/capricorn/src/cap_sup.erl +200 -0
  45. data/erlang/lib/capricorn/src/cap_util.erl +278 -0
  46. data/erlang/lib/capricorn/src/capricorn.erl +45 -0
  47. data/erlang/lib/capricorn/src/capricorn_app.erl +36 -0
  48. data/erlang/lib/emq/ebin/emq.app +17 -0
  49. data/erlang/lib/emq/src/emq.erl +261 -0
  50. data/erlang/lib/emq/src/emq_app.erl +11 -0
  51. data/erlang/lib/emq/src/emq_pool.erl +178 -0
  52. data/erlang/lib/emq/src/emq_queue.erl +332 -0
  53. data/erlang/lib/emq/src/emq_status.erl +148 -0
  54. data/erlang/lib/emq/src/emq_sup.erl +132 -0
  55. data/erlang/lib/gcd/ebin/gcd.app +18 -0
  56. data/erlang/lib/gcd/include/gcd.hrl +5 -0
  57. data/erlang/lib/gcd/rebar.config +3 -0
  58. data/erlang/lib/gcd/src/gcd.erl +51 -0
  59. data/erlang/lib/gcd/src/gcd_app.erl +13 -0
  60. data/erlang/lib/gcd/src/gcd_event.erl +39 -0
  61. data/erlang/lib/gcd/src/gcd_server.erl +30 -0
  62. data/erlang/lib/gcd/src/gcd_srv.erl +186 -0
  63. data/erlang/lib/gcd/src/gcd_sup.erl +18 -0
  64. data/erlang/rebar +0 -0
  65. data/erlang/rebar.config +9 -0
  66. data/erlang/rel/overlay/bin/capricornd +146 -0
  67. data/erlang/rel/overlay/erts-vsn/bin/erl +34 -0
  68. data/erlang/rel/overlay/erts-vsn/bin/nodetool +80 -0
  69. data/erlang/rel/overlay/etc/capricorn/app.config +59 -0
  70. data/erlang/rel/overlay/etc/capricorn/cluster-vm.args +21 -0
  71. data/erlang/rel/overlay/etc/capricorn/machine-vm.args +21 -0
  72. data/erlang/rel/reltool.config +43 -0
  73. data/ext/Makefile +2 -0
  74. data/ext/extconf.rb +1 -0
  75. data/lib/capricorn-client.rb +86 -0
  76. data/lib/capricorn-client/cli/applications.rb +256 -0
  77. data/lib/capricorn-client/cli/gems.rb +57 -0
  78. data/lib/capricorn-client/cli/machines.rb +9 -0
  79. data/lib/capricorn-client/helpers.rb +62 -0
  80. data/lib/capricorn.rb +5 -99
  81. data/lib/capricorn/driver.rb +86 -0
  82. data/lib/capricorn/recipes/apache-debian.rb +112 -0
  83. data/lib/capricorn/recipes/centos-plesk.rb +162 -0
  84. data/lib/capricorn/recipes/macports.rb +54 -0
  85. data/lib/capricorn/system_context.rb +49 -0
  86. data/lib/capricorn/version.rb +5 -0
  87. metadata +233 -74
  88. data/app_generators/engine/engine_generator.rb +0 -40
  89. data/app_generators/engine/templates/Gmfile +0 -20
  90. data/app_generators/engine/templates/MIT-LICENSE.txt +0 -20
  91. data/app_generators/engine/templates/README.rdoc +0 -7
  92. data/app_generators/engine/templates/config/initializers/rails_init.rb +0 -1
  93. data/app_generators/engine/templates/config/routes.rb +0 -2
  94. data/app_generators/engine/templates/gitignore +0 -9
  95. data/app_generators/engine/templates/init.rb +0 -1
  96. data/app_generators/engine/templates/lib/engine.rb +0 -4
  97. data/app_generators/engine/templates/rails/init.rb +0 -1
  98. data/app_generators/engine/templates/tasks/engine_tasks.rake +0 -4
  99. data/bin/capricorn +0 -20
  100. data/lib/capricorn/actor.rb +0 -23
  101. data/lib/capricorn/actor/actions.rb +0 -76
  102. data/lib/capricorn/actors/apache_actor.rb +0 -56
  103. data/lib/capricorn/actors/base_actor.rb +0 -335
  104. data/lib/capricorn/actors/host_file_actor.rb +0 -77
  105. data/lib/capricorn/actors/mysql_actor.rb +0 -20
  106. data/lib/capricorn/actors/passenger_actor.rb +0 -28
  107. data/lib/capricorn/actors/plesk_actor.rb +0 -228
  108. data/lib/capricorn/actors/sqlite3_actor.rb +0 -44
  109. data/lib/capricorn/app_runner.rb +0 -108
  110. data/lib/capricorn/apps/dev.rb +0 -15
  111. data/lib/capricorn/apps/engines.rb +0 -33
  112. data/lib/capricorn/apps/jobs.rb +0 -35
  113. data/lib/capricorn/apps/satellite.rb +0 -68
  114. data/lib/capricorn/apps/server.rb +0 -73
  115. data/lib/capricorn/client.rb +0 -48
  116. data/lib/capricorn/client/auth_token.rb +0 -98
  117. data/lib/capricorn/daemon.rb +0 -81
  118. data/lib/capricorn/exception_handler.rb +0 -79
  119. data/lib/capricorn/extentions/rubygems_plugin.rb +0 -27
  120. data/lib/capricorn/extentions/thor_extentions.rb +0 -32
  121. data/lib/capricorn/job_queue.rb +0 -203
  122. data/lib/capricorn/satellite.rb +0 -52
  123. data/lib/capricorn/satellite/actions.rb +0 -55
  124. data/lib/capricorn/satellite/dependency_loader.rb +0 -82
  125. data/lib/capricorn/satellite/persistence.rb +0 -50
  126. data/lib/capricorn/server.rb +0 -144
  127. data/lib/capricorn/server/daemon.rb +0 -83
  128. data/lib/capricorn/server/proxy.rb +0 -25
  129. data/lib/capricorn/server/security.rb +0 -120
  130. data/lib/capricorn/system.rb +0 -218
  131. data/lib/capricorn/system/config.rb +0 -49
  132. data/lib/capricorn/system/helper.rb +0 -21
  133. data/lib/capricorn/system/options.rb +0 -79
  134. data/lib/capricorn/system/process_user.rb +0 -73
  135. data/lib/capricorn/system/satellites.rb +0 -44
  136. data/lib/capricorn/system/shell.rb +0 -80
  137. data/lib/rubygems_plugin.rb +0 -1
  138. data/spec/actor/actions_spec.rb +0 -13
  139. data/spec/spec_helper.rb +0 -1
@@ -0,0 +1,132 @@
1
+ -module(emq_sup).
2
+ -behaviour(supervisor).
3
+
4
+ -export([start_link/0, stop/0]).
5
+ -export([start_queue/2, setup_process/6, get_emq/1, get_queue/1, get_pool/1, get_status/1]).
6
+ -export([init/1]).
7
+
8
+ start_link() ->
9
+ supervisor:start_link({local, ?MODULE}, ?MODULE, []).
10
+
11
+ stop() ->
12
+ erlang:exit(whereis(?MODULE), normal).
13
+
14
+ start_queue(Name, Options) ->
15
+ Result = supervisor:start_child(?MODULE, {
16
+ Name,
17
+ {emq, start_link, [[{name, Name}| Options]]},
18
+ permanent,
19
+ 5000,
20
+ worker,
21
+ [emq]
22
+ }),
23
+ case Result of
24
+ {ok, _Pid, _Info} ->
25
+ {ok, Name};
26
+ {ok, _Pid} ->
27
+ {ok, Name};
28
+ {error, Reason} ->
29
+ {error, Reason}
30
+ end.
31
+
32
+
33
+
34
+ setup_process(Pid, Name, Emq, Queue, Pool, Status) ->
35
+ gen_server:call(Pid, {setup_process, Name, Emq, Queue, Pool, Status}).
36
+
37
+
38
+
39
+ get_emq(local) ->
40
+ {ok, erlang:get('$emq')};
41
+
42
+ get_emq({remote, Name}) ->
43
+ Children = supervisor:which_children(?MODULE),
44
+ lists:foldl(fun
45
+ ({ChildName, Pid, worker, [emq]}, _) when Name == ChildName ->
46
+ {ok, Pid};
47
+ (_, Acc) ->
48
+ Acc
49
+ end, {error, not_found}, Children);
50
+
51
+ get_emq(Name) ->
52
+ case erlang:get('$emq_name') of
53
+ MyName when MyName == Name ->
54
+ get_emq(local);
55
+ _Else ->
56
+ get_emq({remote, Name})
57
+ end.
58
+
59
+
60
+
61
+ get_queue(local) ->
62
+ {ok, erlang:get('$emq_queue')};
63
+
64
+ get_queue({remote, Name}) ->
65
+ case get_emq({remote, Name}) of
66
+ {ok, Pid} ->
67
+ case gen_server:call(Pid, {'$emq_internal_info'}) of
68
+ {ok, {Name, _Pool, Queue, _Status}} -> {ok, Queue};
69
+ {error, Reason} -> {error, Reason}
70
+ end;
71
+ {error, Reason} -> {error, Reason}
72
+ end;
73
+
74
+ get_queue(Name) ->
75
+ case erlang:get('$emq_name') of
76
+ MyName when MyName == Name ->
77
+ get_queue(local);
78
+ _Else ->
79
+ get_queue({remote, Name})
80
+ end.
81
+
82
+
83
+
84
+ get_pool(local) ->
85
+ {ok, erlang:get('$emq_pool')};
86
+
87
+ get_pool({remote, Name}) ->
88
+ case get_emq({remote, Name}) of
89
+ {ok, Pid} ->
90
+ case gen_server:call(Pid, {'$emq_internal_info'}) of
91
+ {ok, {Name, Pool, _Queue, _Status}} -> {ok, Pool};
92
+ {error, Reason} -> {error, Reason}
93
+ end;
94
+ {error, Reason} -> {error, Reason}
95
+ end;
96
+
97
+ get_pool(Name) ->
98
+ case erlang:get('$emq_name') of
99
+ MyName when MyName == Name ->
100
+ get_pool(local);
101
+ _Else ->
102
+ get_pool({remote, Name})
103
+ end.
104
+
105
+
106
+
107
+ get_status(local) ->
108
+ {ok, erlang:get('$emq_status')};
109
+
110
+ get_status({remote, Name}) ->
111
+ case get_emq({remote, Name}) of
112
+ {ok, Pid} ->
113
+ case gen_server:call(Pid, {'$emq_internal_info'}) of
114
+ {ok, {Name, _Pool, _Queue, Status}} -> {ok, Status};
115
+ {error, Reason} -> {error, Reason}
116
+ end;
117
+ {error, Reason} -> {error, Reason}
118
+ end;
119
+
120
+ get_status(Name) ->
121
+ case erlang:get('$emq_name') of
122
+ MyName when MyName == Name ->
123
+ get_status(local);
124
+ _Else ->
125
+ get_status({remote, Name})
126
+ end.
127
+
128
+
129
+
130
+ init([]) ->
131
+ {ok, {{one_for_one, 10, 3600},[
132
+ ]}}.
@@ -0,0 +1,18 @@
1
+ {application, gcd, [
2
+ {description, "Grand Central Dispatch"},
3
+ {vsn, "0.1"},
4
+ {modules, [
5
+ gcd_app,
6
+ gcd_sup,
7
+ gcd_srv,
8
+ gcd_event,
9
+ gcd_server,
10
+ gcd
11
+ ]},
12
+ {registered, [
13
+ gcd_srv,
14
+ gcd_sup
15
+ ]},
16
+ {applications, [kernel, stdlib]},
17
+ {mod, {gcd_app, []}}
18
+ ]}.
@@ -0,0 +1,5 @@
1
+
2
+ -record(state, {local,remote,nodes,monitors}).
3
+ -record(service, {pid,node,location,name,description}).
4
+ -record(node, {name}).
5
+ -record(monitor, {ref,pid,pattern}).
@@ -0,0 +1,3 @@
1
+ {cover_enabled, true}.
2
+ {erl_opts, [debug_info, fail_on_warning, {i, ".."}]}.
3
+ {lib_dirs, [".."]}.
@@ -0,0 +1,51 @@
1
+ -module(gcd).
2
+ -include("gcd.hrl").
3
+
4
+ -export([start/0, stop/0]).
5
+
6
+ -export([connect/1]).
7
+ -export([register/2, unregister/0]).
8
+ -export([monitor/1, demonitor/1]).
9
+ -export([match_object/1, foldl/2]).
10
+
11
+
12
+ %%% Application API
13
+ start() ->
14
+ application:start(gcd).
15
+
16
+ stop() ->
17
+ application:stop(gcd).
18
+
19
+
20
+ %%% External API
21
+ connect(Node) when is_atom(Node) ->
22
+ connect([Node]);
23
+ connect([]) -> ok;
24
+ connect([Node|Rest]) ->
25
+ net_adm:ping(Node),
26
+ connect(Rest).
27
+
28
+ register(Name, Description) ->
29
+ Info = erlang:process_info(self()),
30
+ RegisteredName = proplists:get_value(registered_name, Info),
31
+ Location =
32
+ case RegisteredName of
33
+ undefined -> self();
34
+ _Else -> {RegisteredName, node()}
35
+ end,
36
+ gen_server:call(gcd_srv, {register, self(), Name, node(), Location, Description}).
37
+
38
+ unregister() ->
39
+ gen_server:call(gcd_srv, {unregister, self()}).
40
+
41
+ monitor(Pattern) ->
42
+ gen_server:call(gcd_srv, {monitor, self(), Pattern}).
43
+
44
+ demonitor(Ref) ->
45
+ gen_server:call(gcd_srv, {demonitor, Ref}).
46
+
47
+ foldl(Fun, Acc) ->
48
+ gen_server:call(gcd_srv, {foldl, Fun, Acc}).
49
+
50
+ match_object(Pattern) ->
51
+ gen_server:call(gcd_srv, {match_object, Pattern}).
@@ -0,0 +1,13 @@
1
+ -module(gcd_app).
2
+ -behaviour(application).
3
+
4
+ -export([start/2, stop/1]).
5
+
6
+ start(_StartType, _StartArgs) ->
7
+ case gcd_sup:start_link() of
8
+ {ok, Pid} -> {ok, Pid};
9
+ Error -> Error
10
+ end.
11
+
12
+ stop(_State) ->
13
+ ok.
@@ -0,0 +1,39 @@
1
+ -module(gcd_event).
2
+ -include("gcd.hrl").
3
+
4
+
5
+ -export([notify/2, sync_notify/2]).
6
+ -export([call/3, call/4]).
7
+
8
+
9
+ notify(Pattern, Message) ->
10
+ [begin
11
+ #service{location=Location} = Service,
12
+ gen_event:notify(Location, Message)
13
+ end ||
14
+ Service <- gcd:match_object(Pattern)].
15
+
16
+
17
+ sync_notify(Pattern, Message) ->
18
+ [begin
19
+ #service{location=Location} = Service,
20
+ gen_event:sync_notify(Location, Message)
21
+ end ||
22
+ Service <- gcd:match_object(Pattern)].
23
+
24
+
25
+ call(Pattern, Handler, Message) ->
26
+ [begin
27
+ #service{location=Location} = Service,
28
+ gen_event:call(Location, Handler, Message)
29
+ end ||
30
+ Service <- gcd:match_object(Pattern)].
31
+
32
+
33
+ call(Pattern, Handler, Message, Timeout) ->
34
+ [begin
35
+ #service{location=Location} = Service,
36
+ gen_event:call(Location, Handler, Message, Timeout)
37
+ end ||
38
+ Service <- gcd:match_object(Pattern)].
39
+
@@ -0,0 +1,30 @@
1
+ -module(gcd_server).
2
+ -include("gcd.hrl").
3
+
4
+
5
+ -export([cast/2]).
6
+ -export([call/2, call/3]).
7
+
8
+
9
+ call(Pattern, Message) ->
10
+ [begin
11
+ #service{location=Location} = Service,
12
+ gen_server:call(Location, Message)
13
+ end ||
14
+ Service <- gcd:match_object(Pattern)].
15
+
16
+
17
+ call(Pattern, Message, Timeout) ->
18
+ [begin
19
+ #service{location=Location} = Service,
20
+ gen_server:call(Location, Message, Timeout)
21
+ end ||
22
+ Service <- gcd:match_object(Pattern)].
23
+
24
+
25
+ cast(Pattern, Message) ->
26
+ [begin
27
+ #service{location=Location} = Service,
28
+ gen_server:cast(Location, Message)
29
+ end ||
30
+ Service <- gcd:match_object(Pattern)].
@@ -0,0 +1,186 @@
1
+ -module(gcd_srv).
2
+ -behaviour(gen_server).
3
+ -include("gcd.hrl").
4
+
5
+ -export([start_link/0]).
6
+ -export([init/1, handle_call/3, handle_cast/2,
7
+ handle_info/2, terminate/2, code_change/3]).
8
+
9
+ -define(L(State), State#state.local).
10
+ -define(R(State), State#state.remote).
11
+ -define(N(State), State#state.nodes).
12
+ -define(M(State), State#state.monitors).
13
+
14
+
15
+ %%% Start the server
16
+ start_link() ->
17
+ gen_server:start_link({local, gcd_srv}, ?MODULE, [], []).
18
+
19
+
20
+ %%% Initialize the server
21
+ init([]) ->
22
+ net_kernel:monitor_nodes(true),
23
+ Local = ets:new(gcd_srv_local, [set,private,{keypos,2}]),
24
+ Remote = ets:new(gcd_srv_remote, [set,private,{keypos,4}]),
25
+ Nodes = ets:new(gcd_srv_nodes, [set,private,{keypos,2}]),
26
+ Monitors = ets:new(gcd_srv_monitors, [set,private,{keypos,2}]),
27
+ {ok, #state{local=Local,remote=Remote,nodes=Nodes,monitors=Monitors}}.
28
+
29
+
30
+ %%% Handle call messages
31
+ handle_call({foldl, Fun, Acc1}, _From, State) ->
32
+ Acc2 = ets:foldl(Fun, Acc1, ?L(State)),
33
+ Acc3 = ets:foldl(Fun, Acc2, ?R(State)),
34
+ {reply, Acc3, State};
35
+
36
+ handle_call({match_object, Pattern}, _From, State) ->
37
+ Services1 = ets:match_object(?L(State), Pattern),
38
+ Services2 = ets:match_object(?R(State), Pattern),
39
+ {reply, Services1 ++ Services2, State};
40
+
41
+ handle_call({register, Pid, Name, Node, Location, Description}, _From, State) ->
42
+ Service = #service{node=Node, location=Location, pid=Pid, name=Name, description=Description},
43
+ case ets:insert_new(?L(State), Service) of
44
+ true ->
45
+ erlang:monitor(process, Pid),
46
+ gen_server:cast(self(), {serviceup, Service}),
47
+ {reply, ok, State};
48
+ false ->
49
+ {reply, {error, already_registerd}, State}
50
+ end;
51
+
52
+ handle_call({unregister, Pid}, _From, State) ->
53
+ case ets:lookup(?L(State), Pid) of
54
+ [Service] ->
55
+ gen_server:cast(self(), {servicedown, Service}),
56
+ ets:delete(?L(State), Pid);
57
+ _ -> ok
58
+ end,
59
+ {reply, ok, State};
60
+
61
+ handle_call({monitor, Pid, Pattern}, _From, State) ->
62
+ Monitor = #monitor{ref=erlang:make_ref(), pid=Pid, pattern=Pattern},
63
+ case ets:insert_new(?M(State), Monitor) of
64
+ true ->
65
+ erlang:monitor(process, Pid),
66
+ {reply, Monitor#monitor.ref, State};
67
+ false ->
68
+ {reply, {error, already_registerd}, State}
69
+ end;
70
+
71
+ handle_call({demonitor, Ref}, _From, State) ->
72
+ ets:delete(?M(State), Ref),
73
+ {reply, ok, State};
74
+
75
+ handle_call(_Request, _From, State) ->
76
+ {reply, ok, State}.
77
+
78
+
79
+ %%% Handle cast messages
80
+ handle_cast({info, Node, Nodes, Services}, State) ->
81
+ ets:insert(?N(State), #node{name=Node}),
82
+ ets:insert(?R(State), Services),
83
+ [net_adm:ping(Node1) || Node1 <- Nodes],
84
+ [gen_server:cast(self(), {serviceup, Service}) || Service <- Services],
85
+ {noreply, State};
86
+
87
+ handle_cast({serviceup, Service}, State) ->
88
+ case Service#service.pid of
89
+ remote ->
90
+ ets:insert(?R(State), Service);
91
+ _Pid ->
92
+ ets:insert(?L(State), Service),
93
+ ets:foldl(fun(#node{name=Node}, _) ->
94
+ gen_server:cast({gcd_srv, Node}, {serviceup, Service#service{pid=remote}})
95
+ end, [], ?N(State))
96
+ end,
97
+
98
+ ets:foldl(fun(#monitor{pattern=Pattern,pid=Pid,ref=Ref}, _) ->
99
+ case ets:test_ms(Service, [{Pattern,[],[true]}]) of
100
+ {ok, true} ->
101
+ Pid ! {serviceup, Ref, Service};
102
+ _Else -> ignore
103
+ end
104
+ end, [], ?M(State)),
105
+
106
+ {noreply, State};
107
+
108
+ handle_cast({servicedown, Service}, State) ->
109
+ case Service#service.pid of
110
+ remote ->
111
+ ets:delete(?R(State), Service#service.location);
112
+ _Pid ->
113
+ ets:delete(?L(State), Service#service.pid),
114
+ ets:foldl(fun(#node{name=Node}, _) ->
115
+ gen_server:cast({gcd_srv, Node}, {servicedown, Service#service{pid=remote}})
116
+ end, [], ?N(State))
117
+ end,
118
+
119
+ ets:foldl(fun(#monitor{pattern=Pattern,pid=Pid,ref=Ref}, _) ->
120
+ case ets:test_ms(Service, [{Pattern,[],[true]}]) of
121
+ {ok, true} ->
122
+ Pid ! {servicedown, Ref, Service};
123
+ _Else -> ignore
124
+ end
125
+ end, [], ?M(State)),
126
+
127
+ {noreply, State};
128
+
129
+ handle_cast(stop, State) ->
130
+ {stop, normal, State};
131
+
132
+ handle_cast(_Msg, State) ->
133
+ {noreply, State}.
134
+
135
+
136
+ %%% Handle generic messages
137
+ handle_info({'DOWN', _Ref, process, Pid, _Reason}, State) ->
138
+ case ets:lookup(?L(State), Pid) of
139
+ [Service] ->
140
+ gen_server:cast(self(), {servicedown, Service}),
141
+ ets:delete(?L(State), Pid);
142
+ _ -> ok
143
+ end,
144
+ Monitors = ets:foldl(fun
145
+ (#monitor{ref=Ref,pid=Pid1}, Acc) when Pid1 == Pid ->
146
+ [Ref|Acc];
147
+ (_Else, Acc) -> Acc
148
+ end, [], ?M(State)),
149
+ [ets:delete(?M(State), Ref) || Ref <- Monitors],
150
+ {noreply, State};
151
+
152
+ handle_info({nodeup, Node}, State) ->
153
+ gen_server:cast({gcd_srv, Node}, {info, node(),
154
+ ets:foldl(fun(#node{name=N}, Acc) -> [N|Acc] end, [], ?N(State)),
155
+ ets:foldl(fun(#service{}=S, Acc) -> [S#service{pid=remote}|Acc] end, [], ?L(State))
156
+ }),
157
+
158
+ {noreply, State};
159
+
160
+ handle_info({nodedown, Node}, State) ->
161
+ ets:delete(?N(State), Node),
162
+
163
+ Keys = ets:foldl(fun
164
+ (#service{node=Node1,location=L}=Service, Acc) when Node1 == Node->
165
+ gen_server:cast(self(), {servicedown, Service}),
166
+ [L|Acc];
167
+ (_Else, Acc) -> Acc
168
+ end, [], ?R(State)),
169
+ [ets:delete(?R(State), Key) || Key <- Keys],
170
+
171
+ {noreply, State};
172
+
173
+ handle_info(_Info, State) ->
174
+ {noreply, State}.
175
+
176
+ %%% Before stopping the server
177
+ terminate(_Reason, State) ->
178
+ ets:delete(?L(State)),
179
+ ets:delete(?R(State)),
180
+ ets:delete(?N(State)),
181
+ ets:delete(?M(State)),
182
+ ok.
183
+
184
+ %%% Code Changes
185
+ code_change(_OldVsn, State, _Extra) ->
186
+ {ok, State}.