have channel_man spawn its own router
Once I added dispatch_fallback to channel_man, it became clear that the router is actually subordinate to the channel_man.
This commit is contained in:
parent
cfd9eb748f
commit
47612c2775
@ -9,7 +9,7 @@
|
||||
-copyright("Jarvis Carroll <spiveehere@gmail.com>").
|
||||
-license("MIT").
|
||||
|
||||
-export([update_router/5, create_channel/3, dispatch_fallback/5]).
|
||||
-export([add_route/4, create_channel/3, dispatch_fallback/5]).
|
||||
%% Worker interface
|
||||
-export([enroll/0]).
|
||||
%% gen_server
|
||||
@ -41,9 +41,17 @@
|
||||
|
||||
%%% Service Interface
|
||||
|
||||
update_router(OurPort, TheirIP, TheirPort, Router, Sock) ->
|
||||
Route = #route{from = OurPort, to = {TheirIP, TheirPort}},
|
||||
gen_server:cast(?MODULE, {update_router, Route, Router, Sock}).
|
||||
% A pretty complex function for an interface, but we need to transfer ownership
|
||||
% of the socket.
|
||||
add_route(Sock, TheirIP, TheirPort, Side) ->
|
||||
% Transfer the socket to the manager. We will then transfer it on to the
|
||||
% router, once it is spawned.
|
||||
case gen_udp:controlling_process(Sock, whereis(?MODULE)) of
|
||||
ok ->
|
||||
gen_server:cast(?MODULE, {add_route, Sock, {TheirIP, TheirPort}, Side});
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
create_channel(OurPort, TheirIP, TheirPort) ->
|
||||
Route = #route{from = OurPort, to = {TheirIP, TheirPort}},
|
||||
@ -89,8 +97,8 @@ handle_call(Unexpected, From, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
handle_cast({update_router, Route, Router, Sock}, State) ->
|
||||
NewState = do_update_router(Route, Router, Sock, State),
|
||||
handle_cast({add_route, Sock, Route, Side}, State) ->
|
||||
NewState = do_add_route(Sock, Route, Side, State),
|
||||
{noreply, NewState};
|
||||
handle_cast({dispatch, Route, ID, Packet}, State) ->
|
||||
NewState = do_dispatch(Route, ID, Packet, State),
|
||||
@ -149,19 +157,21 @@ do_enroll2(PID, State, Channels) ->
|
||||
State
|
||||
end.
|
||||
|
||||
do_update_router(Route, Router, Sock, State = #s{connections = Conns}) ->
|
||||
case maps:find(Route, Conns) of
|
||||
{ok, _Info} ->
|
||||
io:format("Updating routes not yet implemented.~n", []),
|
||||
init:stop();
|
||||
error ->
|
||||
NewConn = #route_info{router = Router,
|
||||
socket = Sock,
|
||||
unused_channels = lists:seq(0, 255),
|
||||
used_channels = #{}},
|
||||
NewConns = maps:put(Route, NewConn, Conns),
|
||||
State#s{connections = NewConns}
|
||||
end.
|
||||
do_add_route(Sock, Peer, Side, State = #s{connections = Conns}) ->
|
||||
{ok, OurPort} = inet:port(Sock),
|
||||
Route = #route{from = OurPort, to = Peer},
|
||||
% Check that this route isn't registered already...
|
||||
% TODO: Maybe detect this case before we transfer the socket? It's all
|
||||
% annoying though.
|
||||
false = maps:is_key(Route, Conns),
|
||||
{ok, Router} = msp_router:start_link(),
|
||||
ok = msp_router:begin_routing(Router, Sock, Peer, Side),
|
||||
NewConn = #route_info{router = Router,
|
||||
socket = Sock,
|
||||
unused_channels = lists:seq(0, 255),
|
||||
used_channels = #{}},
|
||||
NewConns = maps:put(Route, NewConn, Conns),
|
||||
State#s{connections = NewConns}.
|
||||
|
||||
do_create_channel(State = #s{connections = Conns}, Route) ->
|
||||
case maps:find(Route, Conns) of
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
-copyright("Jarvis Carroll <spiveehere@gmail.com>").
|
||||
-license("MIT").
|
||||
|
||||
-export([begin_msp/5]).
|
||||
-export([begin_routing/4]).
|
||||
|
||||
%% gen_server
|
||||
-export([start_link/0]).
|
||||
@ -38,13 +38,13 @@
|
||||
% msp does not negotiate new connections, but once you have a
|
||||
% socket, and a host that knows you will be talking MSP, then a
|
||||
% new msp_router can be initialized.
|
||||
begin_msp(Connection, OurSock, TheirIP, TheirPort, OurSide) ->
|
||||
begin_routing(Router, OurSock, {TheirIP, TheirPort}, OurSide) ->
|
||||
% Transfer the socket to the gen_server. If it is
|
||||
% active then a bunch of messages will be received
|
||||
% at once, but that is fine.
|
||||
case gen_udp:controlling_process(OurSock, Connection) of
|
||||
case gen_udp:controlling_process(OurSock, Router) of
|
||||
ok ->
|
||||
gen_server:cast(Connection, {begin_msp, OurSock, {TheirIP, TheirPort}, OurSide});
|
||||
gen_server:cast(Router, {begin_routing, OurSock, {TheirIP, TheirPort}, OurSide});
|
||||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
@ -69,8 +69,8 @@ handle_call(Unexpected, From, State) ->
|
||||
{reply, undef, State}.
|
||||
|
||||
|
||||
handle_cast({begin_msp, Sock, Peer, Side}, none) ->
|
||||
State = do_begin_msp(Sock, Peer, Side),
|
||||
handle_cast({begin_routing, Sock, Peer, Side}, none) ->
|
||||
State = do_begin_routing(Sock, Peer, Side),
|
||||
{noreply, State};
|
||||
handle_cast(Unexpected, State) ->
|
||||
ok = log(warning, "Unexpected cast: ~tp", [Unexpected]),
|
||||
@ -104,7 +104,7 @@ terminate(_, _) ->
|
||||
|
||||
%%% Doer Functions
|
||||
|
||||
do_begin_msp(Sock, Peer, Side) ->
|
||||
do_begin_routing(Sock, Peer, Side) ->
|
||||
ok = inet:setopts(Sock, [{active, once}, {mode, binary}]),
|
||||
State = #s{socket = Sock,
|
||||
peer = Peer,
|
||||
|
||||
@ -23,17 +23,14 @@ run_tests() ->
|
||||
|
||||
make_connection(OurPort, TheirIP, TheirPort, Side) ->
|
||||
{ok, Sock} = gen_udp:open(OurPort),
|
||||
{ok, Pid} = msp_connection:start_link(),
|
||||
ok = msp_connection:begin_msp(Pid, Sock, TheirIP, TheirPort, Side),
|
||||
ok = msp_channel_man:update_router(OurPort, TheirIP, TheirPort, Pid, Sock),
|
||||
{Pid, Sock}.
|
||||
ok = msp_channel_man:add_route(Sock, TheirIP, TheirPort, Side).
|
||||
|
||||
send_test() ->
|
||||
IP = {127, 0, 0, 1},
|
||||
PortA = 5555,
|
||||
PortB = 6666,
|
||||
{A, SockA} = make_connection(PortA, IP, PortB, 0),
|
||||
{B, SockB} = make_connection(PortB, IP, PortA, 1),
|
||||
ok = make_connection(PortA, IP, PortB, 0),
|
||||
ok = make_connection(PortB, IP, PortA, 1),
|
||||
|
||||
{ok, {ChanA, IndexA}} = msp_channel_man:create_channel(PortA, IP, PortB),
|
||||
msp_channel:send_and_close(ChanA, <<"message sent from A to B">>),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user