Skip to content

Commit

Permalink
[dap] correctly shut down dap when the project node shuts down
Browse files Browse the repository at this point in the history
  • Loading branch information
TheGeorge committed Feb 17, 2021
1 parent df50bd4 commit 77019cb
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
16 changes: 11 additions & 5 deletions apps/els_core/src/els_distribution_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,19 @@ handle_info(Request, State) ->
%%==============================================================================
-spec connect_and_monitor(atom()) -> ok | error.
connect_and_monitor(Node) ->
case net_kernel:connect_node(Node) of
case lists:member(Node, erlang:nodes(connected)) of
true ->
?LOG_INFO("Connected to node [node=~p]", [Node]),
erlang:monitor_node(Node, true),
?LOG_DEBUG("Already connected to node [node=~p]", [Node]),
ok;
false ->
error
case net_kernel:connect_node(Node) of
true ->
?LOG_INFO("Connected to node [node=~p]", [Node]),
erlang:monitor_node(Node, true),
ok;
false ->
error
end
end.

-spec start(atom()) -> ok.
Expand Down Expand Up @@ -170,7 +176,7 @@ wait_connect_and_monitor(Node, Attempts) ->
ok ->
ok;
error ->
?LOG_WARNING( "Trying to connect to node ~p (~p/~p)"
?LOG_DEBUG( "Trying to connect to node ~p (~p/~p)"
, [Node, ?WAIT_ATTEMPTS - Attempts + 1, ?WAIT_ATTEMPTS]),
wait_connect_and_monitor(Node, Attempts - 1)
end.
Expand Down
14 changes: 10 additions & 4 deletions apps/els_dap/src/els_dap_general_provider.erl
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,8 @@ handle_request( {<<"setBreakpoints">>, Params}
SourceBreakpoints = maps:get(<<"breakpoints">>, Params, []),
_SourceModified = maps:get(<<"sourceModified">>, Params, false),
Module = els_uri:module(els_uri:uri(Path)),

els_distribution_server:wait_connect_and_monitor(ProjectNode),


{module, Module} = els_dap_rpc:i(ProjectNode, Module),
Lines = [Line || #{<<"line">> := Line} <- SourceBreakpoints],

Expand Down Expand Up @@ -377,7 +375,7 @@ handle_request({<<"disconnect">>, _Params}, State) ->
els_utils:halt(0),
{#{}, State}.

-spec handle_info(any(), state()) -> state().
-spec handle_info(any(), state()) -> state() | no_return().
handle_info( {int_cb, ThreadPid}
, #{ threads := Threads
, project_node := ProjectNode
Expand All @@ -391,7 +389,15 @@ handle_info( {int_cb, ThreadPid}
els_dap_server:send_event(<<"stopped">>, #{ <<"reason">> => <<"breakpoint">>
, <<"threadId">> => ThreadId
}),
State#{threads => maps:put(ThreadId, Thread, Threads)}.
State#{threads => maps:put(ThreadId, Thread, Threads)};
handle_info({nodedown, Node}, State) ->
%% the project node is down, there is nothing left to do then to exit
?LOG_NOTICE("project node ~p terminated, ending debug session", [Node]),
els_dap_server:send_event(<<"terminated">>, #{}),
els_dap_server:send_event(<<"exited">>, #{ <<"exitCode">> => <<"0">>}),
?LOG_NOTICE("terminating debug adapter"),
els_utils:halt(0),
State.

%%==============================================================================
%% API
Expand Down
21 changes: 20 additions & 1 deletion apps/els_dap/test/els_dap_general_provider_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
frame_variables/1,
navigation_and_frames/1,
set_variable/1,
breakpoints/1
breakpoints/1,
project_node_exit/1
]).

%% TODO: cleanup after dropping support for OTP 21 and 22
Expand Down Expand Up @@ -65,6 +66,7 @@ init_per_testcase(TestCase, Config) when
TestCase =:= undefined orelse
TestCase =:= initialize orelse
TestCase =:= launch_mfa orelse
TestCase =:= launch_mfa_with_cookie orelse
TestCase =:= configuration_done orelse
TestCase =:= configuration_done_with_breakpoint
->
Expand Down Expand Up @@ -391,6 +393,23 @@ breakpoints(Config) ->
?assertMatch([{{els_dap_test_module, 9}, _}], els_dap_rpc:all_breaks(Node)),
ok.

-spec project_node_exit(config()) -> ok.
project_node_exit(Config) ->
NodeName = ?config(node, Config),
Node = binary_to_atom(NodeName),
meck:expect(els_utils, halt, 1, meck:val(ok)),
meck:reset(els_dap_server),
erlang:monitor_node(Node, true),
%% kill node and wait for nodedown message
rpc:cast(Node, erlang, halt, []),
receive
{nodedown, Node} -> ok
end,
%% wait until els_utils:halt has been called
els_dap_test_utils:wait_until_mock_called(els_utils, halt),
?assert(meck:called(els_dap_server, send_event, [<<"terminated">>, '_'])),
?assert(meck:called(els_dap_server, send_event, [<<"exited">>, '_'])).

%%==============================================================================
%% Requests
%%==============================================================================
Expand Down

0 comments on commit 77019cb

Please sign in to comment.