intellij-erlang icon indicating copy to clipboard operation
intellij-erlang copied to clipboard

There are about 800-1000 ERL files in a project, It takes a long time to start up(more then 20minute...), Is it better to load modules dynamically?

Open CenJieTeng opened this issue 3 years ago • 2 comments

My solution was to manually shield all erL files(Modules no to interpret) and load the breakpoint module into the debugger, After adding breakpoints Ctrl+S refreshing /idea/workspace.xml(No auto-refresh method found at present)

mod_server just gen_server simple encapsulation can be ignored:

-module(bp).
-behavior(mod_server).
-include_lib("kernel/include/file.hrl").
-include_lib("xmerl/include/xmerl.hrl").
-define(CHECK_IMPORT_TIMEOUT, 1 * 1000).

-export([start/0, do_init/1, do_call/3, do_cast/2, do_info/2, do_terminate/2, do_code_change/2]).

-record(state,{
  imported_mods = [],
  file_change_time = 0
}).

start() ->
  mod_server:start({local, ?MODULE}, ?MODULE, [], []).

do_init([]) ->
  int:start(),
  erlang:send_after(1, self(), {check_import_timeout}),
  {ok, #state{}}.

do_call(Info, _From, State) ->
  {reply, Info, State}.

do_cast(_Info, State) ->
  {noreply, State}.

do_info({check_import_timeout}, State) ->
  erlang:send_after(?CHECK_IMPORT_TIMEOUT, self(), {check_import_timeout}),
  NewState = check_import_modules(State),
  {noreply, NewState};
do_info(_Info, State) ->
  {noreply, State}.

do_terminate(_Reason, State) ->
  {ok, State}.

do_code_change(_Mod, State) ->
  mod_server:put_callback_mod(?MODULE),
  {ok, State}.

check_import_modules(#state{imported_mods = ImportedMods, file_change_time = FileChangeTime} = State) ->
  {ok, FileInfo} = file:read_file_info(".idea/workspace.xml"),
  if FileInfo#file_info.mtime =/= FileChangeTime ->
    Modules = get_bp_modules(),
    Modules1 = [Mod || Mod <- Modules,not lists:member(Mod, ImportedMods)],
    [int:ni(Mod) || Mod <- Modules1],
    #state{imported_mods =  Modules1 ++ ImportedMods,file_change_time = FileInfo#file_info.mtime};
  true ->
    State
  end.

get_bp_modules() ->
  {XmlDoc, _} = xmerl_scan:file(".idea/workspace.xml", [{encoding, 'utf-8'}]),
  Breakpoints = xmerl_xpath:string("/project/component[@name='XDebuggerManager']/breakpoint-manager/breakpoints/line-breakpoint", XmlDoc),
  lists:foldl(fun(BreakPoint, AccModules) ->
    [#xmlText{value = Url}] = xmerl_xpath:string("url/text()", BreakPoint),
    File = lists:last(re:split(Url, "/", [{return, list}])),
    lists:umerge([list_to_atom(filename:rootname(File))], AccModules)
  end, [], Breakpoints).

CenJieTeng avatar Jan 05 '22 03:01 CenJieTeng

Hi, is there any way to have a sample for reproducing?

ignatov avatar Jan 16 '22 14:01 ignatov

Hi, is there any way to have a sample for reproducing?

-module(bp).
-behavior(gen_server).
-include_lib("kernel/include/file.hrl").
-include_lib("xmerl/include/xmerl.hrl").
-define(CHECK_IMPORT_TIMEOUT, 1 * 1000).

-export([start/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-record(state,{
  imported_mods = [],
  file_change_time = 0
}).

start() ->
  gen_server:start({local, ?MODULE},?MODULE, [], []).

init([]) ->
  int:start(),
  erlang:send_after(1, self(), {check_import_timeout}),
  {ok, #state{}}.

handle_call(Info, _From, State) ->
  {reply, Info, State}.

handle_cast(_Info, State) ->
  {noreply, State}.

handle_info({check_import_timeout}, State) ->
  erlang:send_after(?CHECK_IMPORT_TIMEOUT, self(), {check_import_timeout}),
  NewState = check_import_modules(State),
  {noreply, NewState};
handle_info(_Info, State) ->
  {noreply, State}.

terminate(_Reason, State) ->
  {ok, State}.

code_change(_OldVsn, State, _Extra) ->
  {ok, State}.

check_import_modules(#state{imported_mods = ImportedMods, file_change_time = FileChangeTime} = State) ->
  {ok, FileInfo} = file:read_file_info(".idea/workspace.xml"),
  if FileInfo#file_info.mtime =/= FileChangeTime ->
    Modules = get_bp_modules(),
    Modules1 = [Mod || Mod <- Modules,not lists:member(Mod, ImportedMods)],
    [int:ni(Mod) || Mod <- Modules1],
    #state{imported_mods =  Modules1 ++ ImportedMods,file_change_time = FileInfo#file_info.mtime};
    true ->
      State
  end.

get_bp_modules() ->
  {XmlDoc, _} = xmerl_scan:file(".idea/workspace.xml", [{encoding, 'utf-8'}]),
  Breakpoints = xmerl_xpath:string("/project/component[@name='XDebuggerManager']/breakpoint-manager/breakpoints/line-breakpoint", XmlDoc),
  lists:foldl(fun(BreakPoint, AccModules) ->
    [#xmlText{value = Url}] = xmerl_xpath:string("url/text()", BreakPoint),
    File = lists:last(re:split(Url, "/", [{return, list}])),
    lists:umerge([list_to_atom(filename:rootname(File))], AccModules)
end, [], Breakpoints).

CenJieTeng avatar Jan 26 '22 02:01 CenJieTeng