Basic structure of the IRC modules. Nothing does anything, and I still need to make...
authorMatt Mullins <mokomull@gmail.com>
Mon, 20 Dec 2010 04:26:36 +0000 (22:26 -0600)
committerMatt Mullins <mokomull@gmail.com>
Mon, 20 Dec 2010 04:26:36 +0000 (22:26 -0600)
I made lots of TODO notes in comments.

ebin/erlbot.app [new file with mode: 0644]
src/erlbot.erl [new file with mode: 0644]
src/erlbot_sup.erl [new file with mode: 0644]
src/irc_channel_sup.erl [new file with mode: 0644]
src/irc_conn.erl [new file with mode: 0644]
src/irc_pid_cache.erl [new file with mode: 0644]
src/irc_sup.erl [new file with mode: 0644]
src/irc_user_sup.erl [new file with mode: 0644]
src/pid_cache.erl [new file with mode: 0644]

diff --git a/ebin/erlbot.app b/ebin/erlbot.app
new file mode 100644 (file)
index 0000000..b293147
--- /dev/null
@@ -0,0 +1,3 @@
+{application, erlbot,
+ [{mod, {erlbot, []}}
+ ]}.
diff --git a/src/erlbot.erl b/src/erlbot.erl
new file mode 100644 (file)
index 0000000..39a30b3
--- /dev/null
@@ -0,0 +1,14 @@
+-module(erlbot).
+-behavior(application).
+
+-export([
+          start/2,
+                 stop/1
+               ]).
+
+% TODO: probably should take in a config file through _Args
+start(_Type, _Args) ->
+       erlbot_sup:start_link().
+
+stop(_State) ->
+       ok.
diff --git a/src/erlbot_sup.erl b/src/erlbot_sup.erl
new file mode 100644 (file)
index 0000000..380c45d
--- /dev/null
@@ -0,0 +1,25 @@
+-module(erlbot_sup).
+-behavior(supervisor).
+
+-export([
+          start_link/0
+               ]).
+-export([
+          init/1
+               ]).
+
+start_link() ->
+       supervisor:start_link({local, ?MODULE}, ?MODULE, ok).
+
+init(_Args) ->
+       Children = [child("tamu", "irc.tamu.edu", 6667, "moko|bot")],
+       RestartStrategy = {one_for_one, 0, 1}, % TODO: change to 4 per hour
+       {ok, {RestartStrategy, Children}}.
+
+child(Instance, Host, Port, Nick) ->
+       {{irc, Instance},
+        {irc_sup, start_link, [Instance, Host, Port, Nick]},
+        permanent,
+        brutal_kill,
+        supervisor,
+        [irc_sup]}.
diff --git a/src/irc_channel_sup.erl b/src/irc_channel_sup.erl
new file mode 100644 (file)
index 0000000..dfebef1
--- /dev/null
@@ -0,0 +1,22 @@
+-module(irc_channel_sup).
+-behavior(supervisor).
+
+-export([
+          start_link/1
+        ]).
+
+-export([init/1]).
+
+start_link(Instance) ->
+    supervisor:start_link(?MODULE, Instance).
+
+init(Instance) ->
+    Child = {?MODULE,
+             {irc_channel, start_link, [Instance]},
+             transient,
+             brutal_kill,
+             worker,
+             [irc_channel]},
+    RestartStrategy = {simple_one_for_one, 0, 1},
+    {ok, {RestartStrategy, [Child]}}.
+
diff --git a/src/irc_conn.erl b/src/irc_conn.erl
new file mode 100644 (file)
index 0000000..f2a3ec9
--- /dev/null
@@ -0,0 +1,42 @@
+-module(irc_conn).
+-behavior(gen_server).
+
+-export([
+          start_link/5
+        ]).
+
+-export([
+          init/1,
+          handle_call/3,
+          handle_cast/2,
+          handle_info/2,
+          terminate/2,
+          code_change/3
+        ]).
+
+-record(irc_state, {sup, instance, host, port, nick}).
+
+start_link(Supervisor, Instance, Host, Port, Nick) ->
+    gen_server:start_link(?MODULE,
+        {Supervisor, Instance, Host, Port, Nick}, []).
+
+init({Supervisor, Instance, Host, Port, Nick}) ->
+    State = #irc_state{
+        sup=Supervisor, instance=Instance, host=Host,
+        port=Port, nick=Nick},
+    {ok, State}.
+
+handle_call(_Request, _From, _State) ->
+    {reply, ok, _State}.
+
+handle_cast(_Request, _State) ->
+    {noreply, _State}.
+
+handle_info(_Message, _State) ->
+    {noreply, _State}.
+
+terminate(_Reason, _State) ->
+    ok.
+
+code_change(_OldVsn, State, _Extra) ->
+    {ok, State}.
diff --git a/src/irc_pid_cache.erl b/src/irc_pid_cache.erl
new file mode 100644 (file)
index 0000000..df5b2fd
--- /dev/null
@@ -0,0 +1,28 @@
+-module(irc_pid_cache).
+
+-export([
+          insert_channel/3,
+          get_channel/2,
+          delete_channel/2,
+          insert_user/3,
+          get_user/2,
+          delete_user/2
+        ]).
+
+insert_channel(Instance, Channel, Pid) ->
+    pid_cache:insert({irc_channel, Instance, Channel}, Pid).
+
+get_channel(Instance, Channel) ->
+    pid_cache:get({irc_channel, Instance, Channel}).
+
+delete_channel(Instance, Channel) ->
+    pid_cache:delete({irc_channel, Instance, Channel}).
+
+insert_user(Instance, User, Pid) ->
+    pid_cache:insert({irc_user, Instance, User}, Pid).
+
+get_user(Instance, User) ->
+    pid_cache:get({irc_user, Instance, User}).
+
+delete_user(Instance, User) ->
+    pid_cache:delete({irc_user, Instance, User}).
diff --git a/src/irc_sup.erl b/src/irc_sup.erl
new file mode 100644 (file)
index 0000000..207efe0
--- /dev/null
@@ -0,0 +1,50 @@
+-module(irc_sup).
+-behavior(supervisor).
+
+-export([
+          start_link/4,
+                 get_channel_sup/1,
+                 get_user_sup/1
+               ]).
+-export([init/1]).
+
+start_link(Instance, Host, Port, Nick) ->
+       supervisor:start_link(?MODULE,
+               {Instance, Host, Port, Nick}).
+
+get_channel_sup(Pid) ->
+       get_sup(Pid, channels).
+
+get_user_sup(Pid) ->
+       get_sup(Pid, users).
+
+% TODO: should this crash and burn if the child isn't running?
+%       i.e. can this become a race condition with the actual
+%       respawning of a process?
+get_sup(Pid, Type) ->
+       case supervisor:start_child(Pid,
+                       data_child(Type, ok, []))
+       of
+               {error, {already_started, Child}} ->
+                       Child
+       end.
+
+init({Instance, Host, Port, Nick}) ->
+       Connection = {connection,
+                 {irc_conn, start_link, [self(), Instance, Host, Port, Nick]},
+                 transient, 5, worker, [irc_conn]},
+       Children = [data_child(channels, irc_channel_sup, [Instance]),
+                   data_child(users, irc_user_sup, [Instance]),
+                               Connection
+                          ],
+       RestartStrategy = {one_for_all, 0, 1}, % TODO
+       {ok, {RestartStrategy, Children}}.
+
+data_child(Id, Module, Args) ->
+       {Id,
+        {Module, start_link, Args},
+        permanent,
+        5,
+        supervisor,
+        [Module]}.
+
diff --git a/src/irc_user_sup.erl b/src/irc_user_sup.erl
new file mode 100644 (file)
index 0000000..57c7155
--- /dev/null
@@ -0,0 +1,24 @@
+% TODO: combine with irc_channel_sup
+
+-module(irc_user_sup).
+-behavior(supervisor).
+
+-export([
+          start_link/1
+        ]).
+
+-export([init/1]).
+
+start_link(Instance) ->
+    supervisor:start_link(?MODULE, Instance).
+
+init(Instance) ->
+    Child = {?MODULE,
+             {irc_user, start_link, [Instance]},
+             transient,
+             brutal_kill,
+             worker,
+             [irc_user]},
+    RestartStrategy = {simple_one_for_one, 0, 1},
+    {ok, {RestartStrategy, [Child]}}.
+
diff --git a/src/pid_cache.erl b/src/pid_cache.erl
new file mode 100644 (file)
index 0000000..b9432fd
--- /dev/null
@@ -0,0 +1,22 @@
+-module(pid_cache).
+
+-export([
+          init/0,
+                 insert/2,
+                 get/1,
+                 delete/1
+               ]).
+
+init() ->
+       ets:new(?MODULE, [set, public]).
+
+insert(Key, Value) ->
+       ets:insert(?MODULE, {Key, Value}).
+
+get(Key) ->
+       case ets:lookup(?MODULE, Key) of
+               [{Key, Pid}] -> Pid
+       end.
+
+delete(Key) ->
+       ets:delete(?MODULE, Key).