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,148 @@
1
+ -module(bertrpc_hello_world).
2
+ -behaviour(bertrpc).
3
+
4
+
5
+
6
+ -export([listen_link/1, connect_link/2, hello/2, greet/2, how/2, howl/1, transfer_gem/2]).
7
+ -export([init/1, handle_call/3, handle_cast/2,
8
+ handle_info/2, terminate/2, code_change/3]).
9
+
10
+ -export([test/0]).
11
+
12
+
13
+
14
+ hello(Pid, Name) ->
15
+ bertrpc:call(Pid, hello_world, hello, [Name]).
16
+ greet(Pid, Name) ->
17
+ bertrpc:call(Pid, hello_world, greet, [Name]).
18
+ how(Pid, Name) ->
19
+ gen_server:cast(Pid, {greet, Name}).
20
+ howl(Pid) ->
21
+ bertrpc:cast(Pid, wolf, howl, []).
22
+ transfer_gem(Pid, Chunks) ->
23
+ bertrpc:cast(Pid, gems, transfer, [], [{stream, []}], Chunks).
24
+
25
+
26
+
27
+ %%% Start the server
28
+ listen_link(Port) ->
29
+ bertrpc:listen_link({local, bertrpc_hello_world}, ?MODULE, [], Port).
30
+
31
+ connect_link(Host, Port) ->
32
+ bertrpc:connect_link(Host, Port).
33
+
34
+
35
+
36
+ %%% Initialize the server
37
+ init([]) ->
38
+ State = [],
39
+ {ok, State}.
40
+
41
+
42
+
43
+ %%% Handle call messages
44
+ handle_call({hello_world, hello, [Name], _}, _From, State) ->
45
+ {reply, <<"Hello ", Name/binary>>, State};
46
+
47
+ handle_call({hello_world, greet, [Who], _}=Request, From, _) ->
48
+ Self = self(),
49
+ io:format("call: -> ~p\n", [Request]),
50
+ spawn_link(fun() -> catch receive after 10 ->
51
+ io:format("how\n", []),
52
+ bertrpc_hello_world:how(Self, <<"Hi ">>)
53
+ end end),
54
+ io:format("call: <- ~p\n", [{Who, From}]),
55
+ {noreply, {Who, From}};
56
+
57
+ handle_call(Request, _From, State) ->
58
+ io:format("call: ~p\n", [Request]),
59
+ {reply, ok, State}.
60
+
61
+
62
+
63
+ %%% Handle cast messages
64
+ handle_cast({wolf, howl, [], _}, State) ->
65
+ io:format("Ohh , the werewolf, the werewolf...\n"),
66
+ {noreply, State};
67
+
68
+ handle_cast({greet, How}=Request, {Who, From}) ->
69
+ io:format("cast: -> ~p\n", [Request]),
70
+ bertrpc:reply(From, <<How/binary, Who/binary>>),
71
+ io:format("cast: <- ~p\n", [{noreply, []}]),
72
+ {noreply, []};
73
+
74
+ handle_cast({gems, transfer, _, [{stream, []}]}, _) ->
75
+ do_handle_stream(sos),
76
+ {noreply, []};
77
+
78
+ handle_cast(stop, State) ->
79
+ {stop, normal, State};
80
+
81
+ handle_cast(Msg, State) ->
82
+ io:format("cast: ~p\n", [Msg]),
83
+ {noreply, State}.
84
+
85
+
86
+
87
+ %%% Handle generic messages
88
+ handle_info(_Info, State) ->
89
+ {noreply, State}.
90
+
91
+
92
+
93
+ %%% Before stopping the server
94
+ terminate(_Reason, _State) ->
95
+ ok.
96
+
97
+
98
+
99
+ %%% Code Changes
100
+ code_change(_OldVsn, State, _Extra) ->
101
+ {ok, State}.
102
+
103
+
104
+
105
+ do_handle_stream(sos) ->
106
+ do_handle_stream(bertrpc:stream());
107
+
108
+ do_handle_stream({ok, eof}) ->
109
+ ok;
110
+
111
+ do_handle_stream({error, Reason}) ->
112
+ io:format("~p\n", [{error, Reason}]);
113
+
114
+ do_handle_stream({ok, Chunk}) ->
115
+ io:format("chunk: ~p\n", [binary_to_term(Chunk)]),
116
+ do_handle_stream(bertrpc:stream()).
117
+
118
+
119
+ test() ->
120
+ bertrpc_hello_world:listen_link(5000),
121
+
122
+ {ok, C1} = bertrpc_hello_world:connect_link("localhost", 5000),
123
+ {ok, C2} = bertrpc_hello_world:connect_link("localhost", 5000),
124
+
125
+ io:format("C1: ~p\n", [bertrpc_hello_world:hello(C1, <<"world!">>)]),
126
+ io:format("C2: ~p\n", [bertrpc_hello_world:hello(C2, <<"simon!">>)]),
127
+ io:format("C1: ~p\n", [bertrpc_hello_world:hello(C1, <<"moon!">> )]),
128
+ io:format("C2: ~p\n", [bertrpc_hello_world:hello(C2, <<"anais!">>)]),
129
+
130
+ io:format("C1: ~p\n", [bertrpc_hello_world:greet(C1, <<"World!">>)]),
131
+ io:format("C2: ~p\n", [bertrpc_hello_world:greet(C2, <<"Moon!">>)]),
132
+
133
+ io:format("C1: ~p\n", [bertrpc_hello_world:howl(C1)]),
134
+ io:format("C2: ~p\n", [bertrpc_hello_world:howl(C2)]),
135
+
136
+ io:format("C1: ~p\n", [bertrpc_hello_world:transfer_gem(C1, [
137
+ term_to_binary("hello adrian!"),
138
+ term_to_binary("hello simon!"),
139
+ term_to_binary("hello yves!"),
140
+ term_to_binary("hello bram!"),
141
+ term_to_binary("hello hans!"),
142
+ term_to_binary("hello fred!"),
143
+ term_to_binary("hello inge!")
144
+ ])]),
145
+
146
+ erlang:halt().
147
+
148
+
@@ -0,0 +1,376 @@
1
+ -module(fd_tcp).
2
+ -behaviour(gen_server).
3
+
4
+
5
+ -export([listen_link/5, listen_link/4, listen/5, listen/4]).
6
+ -export([connect_link/6, connect_link/5, connect/6, connect/5]).
7
+ -export([connect_link/4, connect_link/3, connect/4, connect/3]).
8
+ -export([send/1, recv/1, recv/2, call/2, call/3, multi_call/2, multi_call/3, multi_call/4, cast/2, abcast/2, abcast/3, reply/2]).
9
+ -export([close/1]).
10
+
11
+ -export([behaviour_info/1]).
12
+ -export([init/1, handle_call/3, handle_cast/2,
13
+ handle_info/2, terminate/2, code_change/3]).
14
+
15
+
16
+ -record(server, {
17
+ sock, pid,
18
+ callback, args,
19
+ port, options
20
+ }).
21
+
22
+ -record(accept, {
23
+ sock, pid,
24
+ callback, state
25
+ }).
26
+
27
+ -record(client, {
28
+ sock,
29
+ callback, state
30
+ }).
31
+
32
+
33
+ %%% Behaviour API
34
+ behaviour_info(callbacks) ->
35
+ [{init,1}, {handle_call, 3}, {handle_cast, 2}, {handle_data, 2}, {handle_info, 2}, {terminate,2}, {code_change,3}];
36
+ behaviour_info(_) ->
37
+ undefined.
38
+
39
+
40
+ %%% Start the server
41
+ listen_link(Name, Callback, Args, Port, Options) ->
42
+ gen_server:start_link(Name, ?MODULE, {listen, Callback, Args, Port, Options}, []).
43
+
44
+ listen_link(Callback, Args, Port, Options) ->
45
+ gen_server:start_link(?MODULE, {listen, Callback, Args, Port, Options}, []).
46
+
47
+
48
+ listen(Name, Callback, Args, Port, Options) ->
49
+ gen_server:start(Name, ?MODULE, {listen, Callback, Args, Port, Options}, []).
50
+
51
+ listen(Callback, Args, Port, Options) ->
52
+ gen_server:start(?MODULE, {listen, Callback, Args, Port, Options}, []).
53
+
54
+
55
+ %%% Start the client
56
+ connect_link(Name, Callback, Args, Host, Port, Options) ->
57
+ gen_server:start_link(Name, ?MODULE, {connect, Callback, Args, Host, Port, Options}, []).
58
+
59
+ connect_link(Callback, Args, Host, Port, Options) ->
60
+ gen_server:start_link(?MODULE, {connect, Callback, Args, Host, Port, Options}, []).
61
+
62
+
63
+ connect(Name, Callback, Args, Host, Port, Options) ->
64
+ gen_server:start(Name, ?MODULE, {connect, Callback, Args, Host, Port, Options}, []).
65
+
66
+ connect(Callback, Args, Host, Port, Options) ->
67
+ gen_server:start(?MODULE, {connect, Callback, Args, Host, Port, Options}, []).
68
+
69
+
70
+ connect_link(Name, Host, Port, Options) ->
71
+ connect_link(Name, undefined, [], Host, Port, Options).
72
+
73
+ connect_link(Host, Port, Options) ->
74
+ connect_link(undefined, [], Host, Port, Options).
75
+
76
+
77
+ connect(Name, Host, Port, Options) ->
78
+ connect(Name, undefined, [], Host, Port, Options).
79
+
80
+ connect(Host, Port, Options) ->
81
+ connect(undefined, [], Host, Port, Options).
82
+
83
+
84
+ %%% Stop the server
85
+ close(Pid) ->
86
+ gen_server:cast(Pid, fd_tcp_stop).
87
+
88
+
89
+ %%% Send data over the connection
90
+ send(Data) ->
91
+ Sock = get(fd_tcp_sock),
92
+ gen_tcp:send(Sock, Data).
93
+
94
+
95
+ recv(Length) ->
96
+ Sock = get(fd_tcp_sock),
97
+ gen_tcp:recv(Sock, Length).
98
+
99
+ recv(Length, Timeout) ->
100
+ Sock = get(fd_tcp_sock),
101
+ gen_tcp:recv(Sock, Length, Timeout).
102
+
103
+
104
+ call(Pid, Msg) ->
105
+ gen_server:call(Pid, Msg).
106
+
107
+ call(Pid, Msg, Timeout) ->
108
+ gen_server:call(Pid, Msg, Timeout).
109
+
110
+ multi_call(Name, Msg) ->
111
+ gen_server:multi_call(Name, Msg).
112
+
113
+ multi_call(Nodes, Name, Msg) ->
114
+ gen_server:multi_call(Nodes, Name, Msg).
115
+
116
+ multi_call(Nodes, Name, Msg, Timeout) ->
117
+ gen_server:multi_call(Nodes, Name, Msg, Timeout).
118
+
119
+ cast(Pid, Msg) ->
120
+ gen_server:cast(Pid, Msg).
121
+
122
+ abcast(Name, Msg) ->
123
+ gen_server:abcast(Name, Msg).
124
+
125
+ abcast(Nodes, Name, Msg) ->
126
+ gen_server:abcast(Nodes, Name, Msg).
127
+
128
+ reply(Pid, Msg) ->
129
+ gen_server:reply(Pid, Msg).
130
+
131
+
132
+ %%% Initialize the server
133
+ init({listen, Callback, Args, Port, Options}) ->
134
+ {ok, LSock} = gen_tcp:listen(Port, [{reuseaddr, true}|Options]),
135
+ inet:setopts(LSock, [{active, false}]),
136
+ gen_server:cast(self(), fd_tcp_accept),
137
+ {ok, #server{sock=LSock, callback=Callback, args=Args, port=Port, options=Options}};
138
+
139
+ init({accept, Server, LSock, Callback, Args}) ->
140
+ gen_server:cast(self(), fd_tcp_accept),
141
+ {ok, #accept{sock=LSock, pid=Server, callback=Callback, state=Args}};
142
+
143
+ init({connect, Callback, Args, Host, Port, Options}) ->
144
+ {ok, Sock} = gen_tcp:connect(Host, Port, Options),
145
+ inet:setopts(Sock, [{active, once}]),
146
+ put(fd_tcp_sock, Sock),
147
+ if Callback /= undefined ->
148
+ case Callback:init(Args) of
149
+ {ok,State} ->
150
+ {ok, #client{sock=Sock, callback=Callback, state=State}};
151
+ {ok,State,hibernate} ->
152
+ {ok, #client{sock=Sock, callback=Callback, state=State}, hibernate};
153
+ {ok,State,Timeout} ->
154
+ {ok, #client{sock=Sock, callback=Callback, state=State}, Timeout};
155
+ {stop,Reason} ->
156
+ {stop, Reason};
157
+ ignore ->
158
+ ignore
159
+ end;
160
+ true ->
161
+ {ok, #client{sock=Sock}}
162
+ end.
163
+
164
+
165
+ %%% Handle call messages
166
+ handle_call(Msg, From, #accept{}=State) ->
167
+ #accept{ callback=Callback, state=CallbackState } = State,
168
+ Response = Callback:handle_call(Msg, From, CallbackState),
169
+ do_handle_callback_response(Response, State);
170
+
171
+ handle_call(_Msg, _From, #client{callback=undefined}=State) ->
172
+ {reply, ok, State};
173
+
174
+ handle_call(Msg, From, #client{}=State) ->
175
+ #client{ callback=Callback, state=CallbackState } = State,
176
+ Response = Callback:handle_call(Msg, From, CallbackState),
177
+ do_handle_callback_response(Response, State);
178
+
179
+ handle_call(_Msg, _From, #server{}=State) ->
180
+ {reply, ok, State}.
181
+
182
+
183
+ %%% Handle cast messages
184
+ handle_cast(fd_tcp_stop, State) ->
185
+ {stop, normal, State};
186
+
187
+ handle_cast(fd_tcp_accept, #accept{}=State) ->
188
+ #accept{sock=LSock, pid=Server, callback=Callback, state=Args} = State,
189
+ {ok, Sock} = gen_tcp:accept(LSock),
190
+ unlink(Server),
191
+ gen_server:cast(Server, fd_tcp_accept),
192
+ inet:setopts(Sock, [{active, once}]),
193
+ put(fd_tcp_sock, Sock),
194
+ case Callback:init(Args) of
195
+ {ok,NewState} ->
196
+ {noreply, #accept{sock=Sock, pid=Server, callback=Callback, state=NewState}};
197
+ {ok,NewState,hibernate} ->
198
+ {noreply, #accept{sock=Sock, pid=Server, callback=Callback, state=NewState}, hibernate};
199
+ {ok,NewState,Timeout} ->
200
+ {noreply, #accept{sock=Sock, pid=Server, callback=Callback, state=NewState}, Timeout};
201
+ {stop,Reason} ->
202
+ {stop, Reason, #accept{sock=Sock, pid=Server, callback=Callback, state=undefined}};
203
+ ignore ->
204
+ {stop, ignore, #accept{sock=Sock, pid=Server, callback=Callback, state=undefined}}
205
+ end;
206
+
207
+ handle_cast(Msg, #accept{}=State) ->
208
+ #accept{ callback=Callback, state=CallbackState } = State,
209
+ Response = Callback:handle_cast(Msg, CallbackState),
210
+ do_handle_callback_response(Response, State);
211
+
212
+ handle_cast(_Msg, #client{callback=undefined}=State) ->
213
+ {noreply, State};
214
+
215
+ handle_cast(Msg, #client{}=State) ->
216
+ #client{ callback=Callback, state=CallbackState } = State,
217
+ Response = Callback:handle_cast(Msg, CallbackState),
218
+ do_handle_callback_response(Response, State);
219
+
220
+ handle_cast(fd_tcp_accept, #server{}=State) ->
221
+ #server{ sock=LSock, callback=Callback, args=Args } = State,
222
+ {ok, AccPid} = gen_server:start_link(?MODULE, {accept, self(), LSock, Callback, Args}, []),
223
+ {noreply, State#server{pid=AccPid}};
224
+
225
+ handle_cast(_Msg, #server{}=State) ->
226
+ {noreply, State}.
227
+
228
+
229
+ %%% Handle generic messages [ACCEPT]
230
+ handle_info({tcp, Sock, Data}, #accept{sock=Sock}=State) ->
231
+ try
232
+ #accept{ callback=Callback, state=CallbackState } = State,
233
+ Response = Callback:handle_data(Data, CallbackState),
234
+ do_handle_callback_response(Response, State)
235
+ after
236
+ inet:setopts(Sock, [{active, once}])
237
+ end;
238
+
239
+ handle_info({tcp_closed, Sock}, #accept{sock=Sock}=State) ->
240
+ {stop, normal, State};
241
+
242
+ handle_info({tcp_error, Sock, Reason}, #accept{sock=Sock}=State) ->
243
+ {stop, Reason, State};
244
+
245
+ handle_info(Info, #accept{}=State) ->
246
+ #accept{ callback=Callback, state=CallbackState } = State,
247
+ Response = Callback:handle_info(Info, CallbackState),
248
+ do_handle_callback_response(Response, State);
249
+
250
+
251
+ %%% Handle generic messages [CLIENT]
252
+ handle_info({tcp, _Sock, _Data}, #client{callback=undefined}=State) ->
253
+ {noreply, State};
254
+
255
+ handle_info({tcp, Sock, Data}, #client{sock=Sock}=State) ->
256
+ try
257
+ #client{ callback=Callback, state=CallbackState } = State,
258
+ Response = Callback:handle_data(Data, CallbackState),
259
+ do_handle_callback_response(Response, State)
260
+ after
261
+ inet:setopts(Sock, [{active, once}])
262
+ end;
263
+
264
+ handle_info({tcp_closed, Sock}, #client{sock=Sock}=State) ->
265
+ {stop, normal, State};
266
+
267
+ handle_info({tcp_error, Sock, Reason}, #client{sock=Sock}=State) ->
268
+ {stop, Reason, State};
269
+
270
+ handle_info(_Info, #client{callback=undefined}=State) ->
271
+ {noreply, State};
272
+
273
+ handle_info(Info, #client{}=State) ->
274
+ #client{ callback=Callback, state=CallbackState } = State,
275
+ Response = Callback:handle_info(Info, CallbackState),
276
+ do_handle_callback_response(Response, State);
277
+
278
+
279
+ %%% Handle generic messages [SERVER]
280
+ handle_info({'EXIT',AccPid,_Reason}, #server{pid=AccPid}=State) ->
281
+ gen_server:cast(self(), accept),
282
+ {noreply, State#server{pid=undefined}};
283
+
284
+ handle_info(_Info, #server{}=State) ->
285
+ {noreply, State}.
286
+
287
+
288
+ %%% Before stopping the server
289
+ terminate(_Reason, #server{}=State) ->
290
+ #server{ sock = Sock, pid=AccPid } = State,
291
+ erlang:exit(AccPid, kill),
292
+ gen_tcp:close(Sock),
293
+ ok;
294
+
295
+ terminate(Reason, #accept{}=State) ->
296
+ #accept{ sock=Sock, callback=Callback, state=CallbackState } = State,
297
+ Callback:terminate(Reason, CallbackState),
298
+ gen_tcp:close(Sock),
299
+ ok;
300
+
301
+ terminate(Reason, #client{}=State) ->
302
+ #client{ sock=Sock, callback=Callback, state=CallbackState } = State,
303
+ Callback:terminate(Reason, CallbackState),
304
+ gen_tcp:close(Sock),
305
+ ok.
306
+
307
+
308
+ %%% Code Changes
309
+ code_change(_OldVsn, #server{}=State, _Extra) ->
310
+ {ok, State};
311
+
312
+ code_change(OldVsn, #accept{}=State, Extra) ->
313
+ #accept{ callback=Callback, state=CallbackState } = State,
314
+ {ok, NewState} = Callback:code_change(OldVsn, CallbackState, Extra),
315
+ State#accept{ state=NewState };
316
+
317
+ code_change(OldVsn, #client{}=State, Extra) ->
318
+ #client{ callback=Callback, state=CallbackState } = State,
319
+ {ok, NewState} = Callback:code_change(OldVsn, CallbackState, Extra),
320
+ State#client{ state=NewState }.
321
+
322
+
323
+ %%% Internal API
324
+ do_handle_callback_response(Response, #client{}=State) ->
325
+ case Response of
326
+ {reply, Reply, NewCallbackState} ->
327
+ {reply, Reply, State#client{ state=NewCallbackState }};
328
+
329
+ {reply, Reply, NewCallbackState, hibernate} ->
330
+ {reply, Reply, State#client{ state=NewCallbackState }, hibernate};
331
+
332
+ {reply, Reply, NewCallbackState, Timeout} ->
333
+ {reply, Reply, State#client{ state=NewCallbackState }, Timeout};
334
+
335
+ {noreply, NewCallbackState} ->
336
+ {noreply, State#client{ state=NewCallbackState }};
337
+
338
+ {noreply, NewCallbackState, hibernate} ->
339
+ {noreply, State#client{ state=NewCallbackState }, hibernate};
340
+
341
+ {noreply, NewCallbackState, Timeout} ->
342
+ {noreply, State#client{ state=NewCallbackState }, Timeout};
343
+
344
+ {stop, Reason, Reply, NewCallbackState} ->
345
+ {stop, Reason, Reply, State#client{ state=NewCallbackState }};
346
+
347
+ {stop, Reason, NewCallbackState} ->
348
+ {stop, Reason, State#client{ state=NewCallbackState }}
349
+ end;
350
+
351
+ do_handle_callback_response(Response, #accept{}=State) ->
352
+ case Response of
353
+ {reply, Reply, NewCallbackState} ->
354
+ {reply, Reply, State#accept{ state=NewCallbackState }};
355
+
356
+ {reply, Reply, NewCallbackState, hibernate} ->
357
+ {reply, Reply, State#accept{ state=NewCallbackState }, hibernate};
358
+
359
+ {reply, Reply, NewCallbackState, Timeout} ->
360
+ {reply, Reply, State#accept{ state=NewCallbackState }, Timeout};
361
+
362
+ {noreply, NewCallbackState} ->
363
+ {noreply, State#accept{ state=NewCallbackState }};
364
+
365
+ {noreply, NewCallbackState, hibernate} ->
366
+ {noreply, State#accept{ state=NewCallbackState }, hibernate};
367
+
368
+ {noreply, NewCallbackState, Timeout} ->
369
+ {noreply, State#accept{ state=NewCallbackState }, Timeout};
370
+
371
+ {stop, Reason, Reply, NewCallbackState} ->
372
+ {stop, Reason, Reply, State#accept{ state=NewCallbackState }};
373
+
374
+ {stop, Reason, NewCallbackState} ->
375
+ {stop, Reason, State#accept{ state=NewCallbackState }}
376
+ end.