diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d176978
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+*.swp
+*.dump
+*.beam
+Mnesia.*
diff --git a/.gitmodules b/.gitmodules
index 2e9d3a7..4c56fac 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
[submodule "erlang_js"]
path = erlang_js
- url = https://github.com/basho/erlang_js.git
-[submodule "erlv8"]
- path = erlv8
- url = https://github.com/beamjs/erlv8.git
+ url = https://github.com/jonte/erlang_js.git
diff --git a/HOWTO b/HOWTO
index 035800e..2d28ea8 100644
--- a/HOWTO
+++ b/HOWTO
@@ -1,18 +1,21 @@
+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)
+2. git clone git@github.com:jeena/GGS.git (remember to have a local key)
3. cd GGS/
4. git submodule init
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. in new terminal do command: ./python_client 9000
3. back to first terminal
4. ./start
diff --git a/build b/build
index d468113..a9c1c79 100755
--- a/build
+++ b/build
@@ -3,4 +3,4 @@
for i in `find src -name "*.erl"`
do
erlc -o ebin $i
-done
+done
\ No newline at end of file
diff --git a/client b/client
new file mode 100644
index 0000000..dff11aa
--- /dev/null
+++ b/client
@@ -0,0 +1,17 @@
+#!/usr/bin/env ruby -wKU
+
+require 'socket' # Sockets are in standard library
+
+hostname = 'localhost'
+port = 7000
+
+s = TCPSocket.open(hostname, port)
+
+
+
+s.print(q.chop)
+
+while line = s.gets # Read lines from the socket
+ puts "Got Echo: " + line.chop # And print with platform line terminator
+end
+s.close # Close the socket when done
diff --git a/ebin/ggs.app b/ebin/ggs.app
index cafc9df..3315864 100644
--- a/ebin/ggs.app
+++ b/ebin/ggs.app
@@ -3,8 +3,7 @@
{vsn, "0.1.0"},
{modules, [
ggs_app,
- ggs_sup,
- ggs_server
+ ggs_sup
]},
{registered, [ggs_sup]},
{applications, [kernel, stdlib]},
diff --git a/erlv8 b/erlv8
deleted file mode 160000
index 688e503..0000000
--- a/erlv8
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 688e5036864eed01f7aefb6ee8b3a4c22961012f
diff --git a/games/tic-tac-toe-js/index.html b/games/tic-tac-toe-js/index.html
index 97d3c4f..5bdb286 100644
--- a/games/tic-tac-toe-js/index.html
+++ b/games/tic-tac-toe-js/index.html
@@ -12,8 +12,16 @@
function init() {
GameServer.addGame(game_name, main());
- GameServer.addClient(game_name, new TicTacToeClient(frames.player1.document.getElementById("p1"), GameServer));
- GameServer.addClient(game_name, new TicTacToeClient(frames.player2.document.getElementById("p2"), GameServer));
+ GameServer.addClient(
+ game_name,
+ new TicTacToeClient(frames.player1.document.getElementById("p1"),
+ GameServer
+ ));
+ GameServer.addClient(
+ game_name,
+ new TicTacToeClient(frames.player2.document.getElementById("p2"),
+ GameServer
+ ));
}
diff --git a/games/tic-tac-toe-js/proxy.rb b/games/tic-tac-toe-js/proxy.rb
new file mode 100644
index 0000000..e69de29
diff --git a/python_client b/python_client
index 77574e6..9a1f1a9 100755
--- a/python_client
+++ b/python_client
@@ -1,22 +1,78 @@
#!/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
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
-s.send('__hello 0')
+
+# Say hello
+
+print "Saying hello to server"
+s.send(
+"Command: hello\n\
+Content-Type: text\n\
+Content-Length: 0\n\
+\n\
+")
fs = s.makefile()
data = fs.readline()
token = data.split(" ")[0]
print "Token:", token
+print "Data: ", ' '.join(data.split(" ")[1:])
-s.send(token+" __echo 0 msg")
-data = s.recv(1024)
-print data
+# Define ourselves a function!
+
+print "Defining a function called myFun"
+s.send(
+"Token: %s\n\
+Command: define\n\
+Content-Type: text\n\
+Content-Length: 49\n\
+\n\
+function myFun() {return 'Hello World!' ;}" % token)
+fs = s.makefile()
+data = fs.readline()
+print "Token:", token
+print "Data: ", ' '.join(data.split(" ")[1:])
+
+# 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()
+"""
+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"
+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_mnesia_controller_server.erl b/src/ggs_mnesia_controller_server.erl
new file mode 100644
index 0000000..c1f8a10
--- /dev/null
+++ b/src/ggs_mnesia_controller_server.erl
@@ -0,0 +1,68 @@
+-module(ggs_mnesia_controller_server).
+-behaviour(gen_server).
+
+%% API
+-export([start_link/0,
+ stop/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, {}).
+
+%%%====================================================
+%%% API
+%%%====================================================
+
+%%-----------------------------------------------------
+%% @doc Starts the server
+%% @end
+%%-----------------------------------------------------
+start_link() ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
+
+%%-----------------------------------------------------
+%% @doc Stops the server.
+%% @spec stop() -> ok
+%% @end
+%%-----------------------------------------------------
+stop() ->
+ gen_server:cast(?SERVER, stop).
+
+%%-----------------------------------------------------
+%% gen_server callbacks
+%%-----------------------------------------------------
+
+init([]) ->
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ {ok, {}, 0}.
+
+handle_cast(a, State) ->
+ {noreply, State}.
+
+% Request a value from the Mnesia database
+handle_call({getValue, _Key},_From,State) ->
+ {reply,value_of_key_requested_goes_here, State};
+
+% Set a value in the Mnesia database
+handle_call({setValue, _Key, Value},_From,State) ->
+ {reply,value_set_or_updated, State}.
+
+handle_info(timeout, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%-----------------------------------------------------
+%% Internal functions
+%%-----------------------------------------------------
diff --git a/src/ggs_protocol.erl b/src/ggs_protocol.erl
index c470beb..ede5115 100644
--- a/src/ggs_protocol.erl
+++ b/src/ggs_protocol.erl
@@ -1,36 +1,39 @@
-%% This is a parser for JSON implemented using mochijson2
-%% Don't feed it anything other than valid JSON.
-
-module(ggs_protocol).
-export([parse/1]).
parse(Data) ->
- Message = string:tokens(Data, " "),
- io:format(Message),
- case Message of
- ["__get_vms"] ->
- {vms};
- [RefID, "__error", Size, Message ] ->
- {ok, you_said_error};
- [_, "__boot", _ ] ->
- {ok, you_said_boot};
- [RefID, "__stop", _] ->
- {ok, you_said_stop};
- [RefID, "__start", _] ->
- {ok, you_said_start};
- ["__hello", _] ->
- {hello};
- [RefID, "__define",_, JavaScript ] ->
- {ok, you_said_define};
- [RefID, "__echo", Length, Msg ] ->
- {Ref, _} = string:to_integer(RefID),
- {echo, Ref, Length, Msg};
- [RefID, Command, _, Parameter ] ->
- {cmd, Command, Parameter};
- %% Debugging tools, not for production use
- ["__crash"] ->
- {crash, 0};
- %% End debugging tools
- Other ->
- {out_of_bounds, Other}
- end.
+ Message =string:tokens(Data, "\n"),
+ % Turn "A: B" pairs into "{A, B}" tuples, for searching.
+ MsgKV = lists:map((fun(Str) ->
+ list_to_tuple(string:tokens(Str, ": ")) end
+ ), Message),
+ % Hacky way to build a tuple, filter out not_found later on
+ Processed = {
+ case lists:keysearch("Command", 1, MsgKV) of
+ {value,{_, "define"}} ->
+ define;
+ {value,{_, "call"}} ->
+ call;
+ {value,{_, "hello"}} ->
+ hello;
+ false ->
+ not_found
+ end,
+ case lists:keysearch("Token", 1, MsgKV) of
+ {value,{_, Value}} ->
+ Value;
+ false ->
+ not_found
+ end,
+ case lists:keysearch("Content-Length", 1, MsgKV) of
+ {value,{_, Value}} ->
+ {Length, _} = string:to_integer(Value),
+ [_|Cont] = re:split(Data, "\n\n",[{return,list}]),
+ Content = string:join(Cont, "\n\n"),
+ Payload = string:substr(Content,1,Length),
+ Payload;
+ false ->
+ not_found
+ end
+ },
+ gen_server:cast(ggs_server, Processed).
diff --git a/src/ggs_server.erl b/src/ggs_server.erl
deleted file mode 100644
index 097151f..0000000
--- a/src/ggs_server.erl
+++ /dev/null
@@ -1,54 +0,0 @@
-%%%----------------------------------------------------
-%%% @author Jonatan Pålsson
-%%% @copyright 2010 Jonatan Pålsson
-%%% @end
-%%%----------------------------------------------------
-
--module(ggs_server).
-
-% import
--import(ggs_network).
-
-%% API
--export([start_link/0, start_link/1, stop/0 ]).
-%-export([crash/0, vms/0, hello/0, echo/0]).
--export([get_count/0]).
-
-
-%%%====================================================
-%%% API
-%%%====================================================
-
-%%-----------------------------------------------------
-%% @doc Starts the server
-%% @end
-%%-----------------------------------------------------
-start_link() ->
- ggs_network:start_link().
-
-start_link(Port) ->
- ggs_network:start_link(Port).
-
-
-%%-----------------------------------------------------
-%% @doc Fetches the number of requests made to this server
-%% @spec get_count() -> {ok, Count}
-%% where
-%% Count = integer()
-%% @end
-%%-----------------------------------------------------
-get_count() ->
- ggs_network:get_count(get_count).
-
-%crash() -> gss_network:crash().
-%vms() -> gss_network:vms().
-%hello() -> gss_network:hello().
-%echo() -> gss_network:echo().
-
-%%-----------------------------------------------------
-%% @doc Stops the server.
-%% @spec stop() -> ok
-%% @end
-%%-----------------------------------------------------
-stop() ->
- ggs_network:stop().
diff --git a/src/ggs_server_sup.erl b/src/ggs_server_sup.erl
new file mode 100644
index 0000000..23d32f7
--- /dev/null
+++ b/src/ggs_server_sup.erl
@@ -0,0 +1,48 @@
+-module(ggs_server_sup).
+-behaviour(supervisor).
+
+%% API
+-export([start/1, start_link/1]).
+
+%% Supervisor callbacks
+-export([init/1]).
+-define(SERVER, ?MODULE).
+
+start(Port) ->
+ [FirstArg] = Port,
+ {IntPort, _} = string:to_integer(FirstArg),
+ start_link(IntPort).
+
+start_link(Port) ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, [Port]).
+
+init([Port]) ->
+ GGSServer = {ggs_server,
+ {ggs_server, start_link, [Port]},
+ permanent,
+ 2000,
+ 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,
+ 2000,
+ worker,
+ [ggs_mnesia_controller_server]
+ },
+ Children = [MnesiaServer, Backup, GGSServer],
+
+ RestartStrategy = { one_for_one, % Restart only crashing child
+ 10, % Allow ten crashes per..
+ 1 % 1 second, then crash supervisor.
+ },
+ {ok, {RestartStrategy, Children}}.
+
diff --git a/src/ggs_sup.erl b/src/ggs_sup.erl
index 0cc8335..ee6f8cd 100644
--- a/src/ggs_sup.erl
+++ b/src/ggs_sup.erl
@@ -17,12 +17,12 @@ start_link(Port) ->
supervisor:start_link({local, ?SERVER}, ?MODULE, [Port]).
init([Port]) ->
- Server = {ggs_server,
- {ggs_server, start_link, [Port]},
+ Server = {ggs_server_sup,
+ {ggs_server_sup, start_link, [Port]},
permanent,
2000,
worker,
- [ggs_server]
+ [ggs_server_sup]
},
Children = [Server],
diff --git a/src/js_runner.erl b/src/js_runner.erl
deleted file mode 100644
index ca866c4..0000000
--- a/src/js_runner.erl
+++ /dev/null
@@ -1,13 +0,0 @@
--module(js_runner).
--export([define/2,call/3, boot/0]).
-
-boot() ->
- erlang_js:start(),
- {ok, Port} = js_driver:new(),
- Port.
-
-define(Port, Data) ->
- ok = js:define(Port, list_to_binary(Data)).
-
-call(Port, Func, Params) ->
- js:call(Port, list_to_binary(Func), Params).
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 f3720a5..6de5737 100755
--- a/start
+++ b/start
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
-erl -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