Now we have a backup server which keeps track of ggs_server's state between crashes. JSVM doesn't seem to survive crash even though port to it is backed up by ggs_backup..
This commit is contained in:
parent
adfc9b41dd
commit
79777e7b1c
4 changed files with 104 additions and 16 deletions
|
@ -1,8 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
import socket
|
||||
import sys, time, socket
|
||||
|
||||
HOST = 'localhost' # The remote host
|
||||
PORT = int(sys.argv[1]) # The same port as used by the server
|
||||
|
@ -53,5 +51,21 @@ fs = s.makefile()
|
|||
data = fs.readline()
|
||||
print "Token:", token
|
||||
print "Data: ", ' '.join(data.split(" ")[1:])
|
||||
s.close()
|
||||
|
||||
|
||||
# Call that function!
|
||||
|
||||
print "Calling myFun"
|
||||
s.send(
|
||||
"Token: %s\n\
|
||||
Command: call\n\
|
||||
Content-Type: text\n\
|
||||
Content-Length: 6\n\
|
||||
\n\
|
||||
myFun" % token)
|
||||
fs = s.makefile()
|
||||
data = fs.readline()
|
||||
print "Token:", token
|
||||
print "Data: ", ' '.join(data.split(" ")[1:])
|
||||
|
||||
s.close()
|
||||
|
|
41
src/ggs_backup.erl
Normal file
41
src/ggs_backup.erl
Normal file
|
@ -0,0 +1,41 @@
|
|||
-module(ggs_backup).
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% API
|
||||
-export([start_link/0 ]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2,
|
||||
handle_info/2, terminate/2, code_change/3]).
|
||||
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
-record(state, {port, lsock, client_vm_map = []}).
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
||||
|
||||
init([]) ->
|
||||
{ok, #state{port = -1, lsock = -1, client_vm_map = -1}, 0}.
|
||||
|
||||
handle_call(get_backup, _From, State) ->
|
||||
BackedUpState = case State of
|
||||
#state{port = -1, lsock = -1, client_vm_map = -1} ->
|
||||
not_initialized;
|
||||
Other ->
|
||||
Other
|
||||
end,
|
||||
{reply, {backup_state, BackedUpState}, State}.
|
||||
|
||||
handle_cast({set_backup, NewState}, _State) ->
|
||||
{noreply, NewState}.
|
||||
|
||||
handle_info(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
|
@ -34,9 +34,12 @@
|
|||
%% @end
|
||||
%%-----------------------------------------------------
|
||||
start_link(Port) ->
|
||||
process_flag(trap_exit, true),
|
||||
gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).
|
||||
|
||||
start_link(start_as_slave, State) ->
|
||||
gen_server:start_link({local, ?SERVER}, ?MODULE,
|
||||
[start_as_slave, State], []).
|
||||
|
||||
start_link() ->
|
||||
start_link(?DEFAULT_PORT).
|
||||
|
||||
|
@ -63,12 +66,23 @@ stop() ->
|
|||
%%-----------------------------------------------------
|
||||
|
||||
init([Port]) ->
|
||||
{ok, LSock} = gen_tcp:listen(Port, [{active, true},
|
||||
{reuseaddr, true}]),
|
||||
{ok, #state{port = Port, lsock = LSock}, 0}.
|
||||
case gen_server:call(ggs_backup, get_backup) of
|
||||
{backup_state, not_initialized} ->
|
||||
{ok, LSock} = gen_tcp:listen(Port, [{active, true},
|
||||
{reuseaddr, true}]),
|
||||
{ok, #state{port = Port, lsock = LSock}, 0};
|
||||
{backup_state, State} ->
|
||||
{ok, LSock} = gen_tcp:listen(Port, [{active, true},
|
||||
{reuseaddr, true}]),
|
||||
{ok, State#state{lsock = LSock}, 0}
|
||||
end.
|
||||
|
||||
handle_call(get_count, _From, State) ->
|
||||
{reply, {ok, State#state.client_vm_map}, State}.
|
||||
{reply, {ok, State#state.client_vm_map}, State};
|
||||
|
||||
handle_call({backup_state, OldState}, _From, State) ->
|
||||
io:format("Received old state from backup~n"),
|
||||
{noreply, OldState}.
|
||||
|
||||
handle_cast(stop, State) ->
|
||||
{stop, normal, State}.
|
||||
|
@ -79,12 +93,16 @@ handle_info({tcp, Socket, RawData}, State) ->
|
|||
io:format("Old map: ~p NewState: ~p~n", [OldMap, NewState]),
|
||||
{noreply, State#state{client_vm_map = OldMap ++ [NewState]}};
|
||||
|
||||
handle_info({tcp_closed, _}, State) ->
|
||||
handle_info({tcp_closed, Socket}, State) ->
|
||||
gen_tcp:close(Socket),
|
||||
{stop, "Client closed socket", State};
|
||||
|
||||
handle_info(timeout, #state{lsock = LSock} = State) ->
|
||||
{ok, _Sock} = gen_tcp:accept(LSock),
|
||||
{noreply, State}.
|
||||
{noreply, State};
|
||||
|
||||
handle_info(Other, State) ->
|
||||
erlang:display(Other).
|
||||
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
@ -105,6 +123,7 @@ do_JSCall(Socket, Data, State) ->
|
|||
send(Socket, Token, "Okay, defined that for you!"),
|
||||
[];
|
||||
{call, Token, Payload} ->
|
||||
io:format("Got call request: ~p~n", [Payload]),
|
||||
JSVM = getJSVM(Token, State),
|
||||
{ok, Ret} = js_runner:call(JSVM, Payload, []),%Payload, []),
|
||||
send(Socket, Token, "JS says:", binary_to_list(Ret));
|
||||
|
@ -114,6 +133,13 @@ do_JSCall(Socket, Data, State) ->
|
|||
JSVM = js_runner:boot(),
|
||||
Client = getRef(),
|
||||
send(Socket, Client, "This is your refID"),
|
||||
|
||||
%% This shouldnt be here...
|
||||
OldMap = State#state.client_vm_map,
|
||||
BackupState = State#state{client_vm_map = OldMap ++ [{Client, JSVM}]},
|
||||
gen_server:cast(ggs_backup, {set_backup, BackupState}),
|
||||
%%
|
||||
|
||||
{Client, JSVM};
|
||||
{echo, RefID, _, MSG} ->
|
||||
send(Socket, RefID, "Your VM is ", getJSVM(RefID, State)),
|
||||
|
@ -121,11 +147,11 @@ do_JSCall(Socket, Data, State) ->
|
|||
{crash, Zero} ->
|
||||
10/Zero;
|
||||
{vms} ->
|
||||
send(Socket, "RefID", State)
|
||||
send(Socket, "RefID", State);
|
||||
% Set the new state to []
|
||||
% Other ->
|
||||
% send(Socket, "RefID", "__error"),
|
||||
% []
|
||||
Other ->
|
||||
send(Socket, "RefID", "__error"),
|
||||
[]
|
||||
end,
|
||||
% Return the new state
|
||||
NewState.
|
||||
|
|
|
@ -24,6 +24,13 @@ init([Port]) ->
|
|||
worker,
|
||||
[ggs_server]
|
||||
},
|
||||
Backup = {ggs_backup,
|
||||
{ggs_backup, start_link, []},
|
||||
permanent,
|
||||
2000,
|
||||
worker,
|
||||
[ggs_backup]
|
||||
},
|
||||
MnesiaServer = {ggs_mnesia_controller_server,
|
||||
{ggs_mnesia_controller_server, start_link, []},
|
||||
permanent,
|
||||
|
@ -31,7 +38,7 @@ init([Port]) ->
|
|||
worker,
|
||||
[ggs_mnesia_controller_server]
|
||||
},
|
||||
Children = [MnesiaServer, GGSServer],
|
||||
Children = [MnesiaServer, Backup, GGSServer],
|
||||
|
||||
RestartStrategy = { one_for_one, % Restart only crashing child
|
||||
10, % Allow ten crashes per..
|
||||
|
|
Reference in a new issue