From 79777e7b1c88c3ce073b8d00b511383ddcc1bf87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Sat, 5 Feb 2011 15:24:30 +0100 Subject: [PATCH 1/3] 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.. --- python_client | 22 +++++++++++++++---- src/ggs_backup.erl | 41 ++++++++++++++++++++++++++++++++++++ src/ggs_server.erl | 48 ++++++++++++++++++++++++++++++++---------- src/ggs_server_sup.erl | 9 +++++++- 4 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 src/ggs_backup.erl 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.. From 7267781b6458bce588c8116496ccaf7513b0b285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20P=C3=A5lsson?= Date: Sun, 6 Feb 2011 14:43:31 +0100 Subject: [PATCH 2/3] Starting erlang_js properly, and modified python_client tot start two sequential connections --- python_client | 5 +++++ src/ggs_server.erl | 5 +---- src/start_ggs.erl | 1 + start | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/python_client b/python_client index daa2a19..4dd82ae 100755 --- a/python_client +++ b/python_client @@ -52,7 +52,12 @@ data = fs.readline() print "Token:", token print "Data: ", ' '.join(data.split(" ")[1:]) +s.close() +HOST = 'localhost' # The remote host +PORT = int(sys.argv[1]) # The same port as used by the server +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect((HOST, PORT)) # Call that function! print "Calling myFun" diff --git a/src/ggs_server.erl b/src/ggs_server.erl index 2bd1aeb..dff29f3 100644 --- a/src/ggs_server.erl +++ b/src/ggs_server.erl @@ -36,10 +36,6 @@ start_link(Port) -> 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). @@ -125,6 +121,7 @@ do_JSCall(Socket, Data, State) -> {call, Token, Payload} -> io:format("Got call request: ~p~n", [Payload]), JSVM = getJSVM(Token, State), + erlang:display(erlang:port_info(JSVM)), {ok, Ret} = js_runner:call(JSVM, Payload, []),%Payload, []), send(Socket, Token, "JS says:", binary_to_list(Ret)); diff --git a/src/start_ggs.erl b/src/start_ggs.erl index eabdbc5..3955715 100644 --- a/src/start_ggs.erl +++ b/src/start_ggs.erl @@ -3,4 +3,5 @@ start() -> application:start(inets), + application:start(erlang_js), application:start(ggs). diff --git a/start b/start index 37040d3..6de5737 100755 --- a/start +++ b/start @@ -1,3 +1,3 @@ #!/usr/bin/env bash -erl -mnesia -boot start_sasl -pa erlang_js/ebin/ -pa ebin -pa src -s start_ggs +erl -sname ggs -mnesia -boot start_sasl -pa erlang_js/ebin/ -pa ebin -pa src -s start_ggs From e8c93893d297ea4d01f9abf7a06bf557fcb83caf Mon Sep 17 00:00:00 2001 From: Kallfaktorn Date: Sat, 5 Feb 2011 16:27:06 +0100 Subject: [PATCH 3/3] New installation notes. --- HOWTO | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/HOWTO b/HOWTO index 035800e..8fbba1f 100644 --- a/HOWTO +++ b/HOWTO @@ -1,3 +1,6 @@ +PREREQUISITES: +python version 2.x set to default. + INSTALL 1. Cd into directory where you to have the project 2. git-clone git@github.com:jeena/GGS.git (remember to have a local key) @@ -6,13 +9,13 @@ INSTALL 5. git submodule update 6. cd erlang_js 7. make -8. make test (If not all tests are passed then you are screwed!) +8. make test (Optional. It has to work though.) 10. cd ../ 11. ./build 12. USAGE 1. start a second terminal -2. telnet localhost 7000 +2. ./python_client 9000 3. back to first terminal 4. ./start