diff --git a/python_client b/python_client index f8c5496..daa2a19 100755 --- a/python_client +++ b/python_client @@ -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() diff --git a/src/ggs_backup.erl b/src/ggs_backup.erl new file mode 100644 index 0000000..30c80a2 --- /dev/null +++ b/src/ggs_backup.erl @@ -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. diff --git a/src/ggs_server.erl b/src/ggs_server.erl index 4226737..2bd1aeb 100644 --- a/src/ggs_server.erl +++ b/src/ggs_server.erl @@ -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. diff --git a/src/ggs_server_sup.erl b/src/ggs_server_sup.erl index df665d6..23d32f7 100644 --- a/src/ggs_server_sup.erl +++ b/src/ggs_server_sup.erl @@ -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..