浏览代码

fx: 由于windows平台下 fsnotify存在bug 可能文件并没有任何改动,但是会触发写的事件, 所以erlang添加了二次检查文件时间戳的逻辑 收到文件修改的事件时再次检查一下时间戳 确保事件真实被改动过 在执行后续加载或编译流程

master
SisMaker 4 年前
父节点
当前提交
ecd78f78f7
共有 2 个文件被更改,包括 179 次插入122 次删除
  1. +51
    -54
      src/sync/esSyncSrv.erl
  2. +128
    -68
      src/sync/esUtils.erl

+ 51
- 54
src/sync/esSyncSrv.erl 查看文件

@ -124,67 +124,64 @@ handleCast({miSyncNode, IsSync}, _, State) ->
{kpS, State#state{swSyncNode = false}}
end;
handleCast(miRescan, _, State) ->
SrcFiles = esUtils:collSrcFiles(false),
{kpS_S, State#state{srcFiles = SrcFiles}};
{Srcs, Hrls, Configs, Beams} = esUtils:collSrcFiles(false),
{kpS_S, State#state{srcFiles = Srcs, hrlFiles = Hrls, configs = Configs, beams = Beams}};
handleCast(_Msg, _, _State) ->
kpS_S.
handleInfo({_Port, {data, Data}}, running, #state{srcFiles = SrcFiles, onSyncFun = OnSyncFun, swSyncNode = SwSyncNode} = State) ->
FileList = binary:split(Data, <<"\r\n">>, [global]),
%% beam hrl src
{Beams, Hrls, Srcs, Configs} = esUtils:classifyChangeFile(FileList, [], [], [], []),
esUtils:fireOnsync(OnSyncFun, Configs),
esUtils:reloadChangedMod(Beams, SwSyncNode, OnSyncFun, []),
case ?esCfgSync:getv(?compileCmd) of
undefined ->
esUtils:recompileChangeHrlFile(Hrls, SrcFiles, SwSyncNode),
esUtils:recompileChangeSrcFile(Srcs, SwSyncNode),
NewSrcFiles = esUtils:addNewFile(Srcs, SrcFiles),
{kpS, State#state{srcFiles = NewSrcFiles}};
CmdStr ->
case Srcs =/= [] orelse Hrls =/= [] of
true ->
RetStr = os:cmd(CmdStr),
RetList = string:split(RetStr, "\n", all),
CmdMsg = io_lib:format("compile cmd:~p ~n", [CmdStr]),
esUtils:logSuccess(CmdMsg),
RetMsg = io_lib:format("the result: ~n ", []),
esUtils:logSuccess(RetMsg),
[
begin
OneMsg = io_lib:format("~p ~n", [OneRet]),
esUtils:logSuccess(OneMsg)
end || OneRet <- RetList, OneRet =/= []
],
ok;
_ ->
ignore
end,
kpS_S
end;
handleInfo({_Port, {data, Data}}, _, #state{port = Port} = State) ->
case Data of
<<"init">> ->
%% port启动成功
{AddSrcDirs, OnlySrcDirs, DelSrcDirs} = esUtils:mergeExtraDirs(false),
AddStr = string:join([filename:nativename(OneDir) || OneDir <- AddSrcDirs], "|"),
OnlyStr = string:join([filename:nativename(OneDir) || OneDir <- OnlySrcDirs], "|"),
DelStr = string:join([filename:nativename(OneDir) || OneDir <- DelSrcDirs], "|"),
AllStr = string:join([AddStr, OnlyStr, DelStr], "\r\n"),
erlang:port_command(Port, AllStr),
esUtils:logSuccess("eSync connect fileSync success..."),
handleInfo({Port, {data, Data}}, Status, #state{srcFiles = Srcs, hrlFiles = Hrls, configs = Configs, beams = Beams, onSyncFun = OnSyncFun, swSyncNode = SwSyncNode} = State) ->
case Status of
running ->
FileList = binary:split(Data, <<"\r\n">>, [global]),
%% beam hrl src
{CBeams, CConfigs, CHrls, CSrcs, NewSrcs, NewHrls, NewConfigs, NewBeams} = esUtils:classifyChangeFile(FileList, [], [], [], #{}, Srcs, Hrls, Configs, Beams),
esUtils:fireOnsync(OnSyncFun, CConfigs),
esUtils:reloadChangedMod(CBeams, SwSyncNode, OnSyncFun, []),
case ?esCfgSync:getv(?compileCmd) of
undefined ->
%% src文件
SrcFiles = esUtils:collSrcFiles(true),
{nextS, running, State#state{srcFiles = SrcFiles}};
_ ->
{nextS, running, State}
NReSrcs = esUtils:recompileChangeHrlFile(CHrls, NewSrcs, CSrcs),
esUtils:recompileChangeSrcFile(maps:iterator(NReSrcs), SwSyncNode),
{kpS, State#state{srcFiles = NewSrcs, hrlFiles = NewHrls, configs = NewConfigs, beams = NewBeams}};
CmdStr ->
case maps:size(CSrcs) > 0 orelse CHrls =/= [] of
true ->
RetStr = os:cmd(CmdStr),
RetList = string:split(RetStr, "\n", all),
CmdMsg = io_lib:format("compile cmd:~p ~n", [CmdStr]),
esUtils:logSuccess(CmdMsg),
RetMsg = io_lib:format("the result: ~n ", []),
esUtils:logSuccess(RetMsg),
[
begin
OneMsg = io_lib:format("~p ~n", [OneRet]),
esUtils:logSuccess(OneMsg)
end || OneRet <- RetList, OneRet =/= []
],
ok;
_ ->
ignore
end,
kpS_S
end;
_ ->
Msg = io_lib:format("error, esSyncSrv receive unexpect port msg ~p~n", [Data]),
esUtils:logErrors(Msg),
kpS_S
case Data of
<<"init">> ->
%% port启动成功
{AddSrcDirs, OnlySrcDirs, DelSrcDirs} = esUtils:mergeExtraDirs(false),
AddStr = string:join([filename:nativename(OneDir) || OneDir <- AddSrcDirs], "|"),
OnlyStr = string:join([filename:nativename(OneDir) || OneDir <- OnlySrcDirs], "|"),
DelStr = string:join([filename:nativename(OneDir) || OneDir <- DelSrcDirs], "|"),
AllStr = string:join([AddStr, OnlyStr, DelStr], "\r\n"),
erlang:port_command(Port, AllStr),
esUtils:logSuccess("eSync connect fileSync success..."),
%% src文件
{BSrcs, BHrls, BConfigs, BBeams} = esUtils:collSrcFiles(true),
{nextS, running, State#state{srcFiles = BSrcs, hrlFiles = BHrls, configs = BConfigs, beams = BBeams}};
_ ->
ErrMsg = io_lib:format("error, esSyncSrv receive unexpect port msg ~p~n", [Data]),
esUtils:logErrors(ErrMsg),
kpS_S
end
end;
handleInfo({_Port, closed}, running, _State) ->
Msg = io_lib:format("esSyncSrv receive port closed ~n", []),

+ 128
- 68
src/sync/esUtils.erl 查看文件

@ -102,8 +102,8 @@ tryGetSrcOptions(SrcDir) ->
tryGetSrcOptions(NewDirName);
_ when IsBaseSrcDir ->
try filelib:fold_files(SrcDir, ".*\\.(erl|dtl|lfe|ex)$", true,
fun(OneFiles, Acc) ->
Mod = binary_to_atom(filename:basename(OneFiles, filename:extension(OneFiles))),
fun(OneFile, Acc) ->
Mod = binary_to_atom(filename:basename(OneFile, filename:extension(OneFile))),
case tryGetModOptions(Mod) of
{ok, _Options} = Opts ->
throw(Opts);
@ -368,34 +368,35 @@ mergeExtraDirs(IsAddPath) ->
lists:foldl(FunMerge, {[], [], []}, ExtraList)
end.
-define(IIF(Cond, Ret1, Ret2), (case Cond of true -> Ret1; _ -> Ret2 end)).
collSrcFiles(IsAddPath) ->
{AddSrcDirs, OnlySrcDirs, DelSrcDirs} = mergeExtraDirs(IsAddPath),
CollFiles = filelib:fold_files(filename:absname(<<"./">>), ".*\\.(erl|dtl|lfe|ex)$", true,
fun(OneFiles, {Srcs, Hrls, Configs, Beams} = Acc) ->
case isOnlyDir(OnlySrcDirs, OneFiles) andalso (not isDelDir(DelSrcDirs, OneFiles)) of
CollFiles = filelib:fold_files(filename:absname(<<"./">>), ".*\\.(erl|hrl|beam|config|dtl|lfe|ex)$", true,
fun(OneFile, {Srcs, Hrls, Configs, Beams} = Acc) ->
case isOnlyDir(OnlySrcDirs, OneFile) andalso (not isDelDir(DelSrcDirs, OneFile)) of
true ->
MTime = filelib:last_modified(OneFiles),
case filename:extension(OneFiles) of
MTimeSec = esUtils:dateTimeToSec(filelib:last_modified(OneFilespan>)),
case filename:extension(OneFile) of
<<".beam">> ->
Module = binary_to_atom(filename:basename(OneFile, <<".beam">>)),
;
<<".hrl">> ->
[OneFile | Hrls];
BeamMod = binary_to_atom(filename:basename(OneFile, <<".beam">>)),
setelement(4, Acc, Beams#{BeamMod => MTimeSec});
<<".config">> ->
[OneFile | Configs];
setelement(3, Acc, Configs#{OneFile => MTimeSec});
<<".hrl">> ->
setelement(2, Acc, Hrls#{OneFile => MTimeSec});
<<>> ->
Acc;
_ ->
RootSrcDir =
case getRootSrcDirFromSrcDir(OneFiles) of
case getRootSrcDirFromSrcDir(OneFile) of
undefined ->
filename:dirname(OneFiles);
filename:dirname(OneFile);
RetSrcDir ->
RetSrcDir
end,
case getOptions(RootSrcDir) of
undefined ->
Mod = binary_to_atom(filename:basename(OneFiles, filename:extension(OneFiles))),
Mod = binary_to_atom(filename:basename(OneFile, filename:extension(OneFile))),
case getModOptions(Mod) of
{ok, Options} ->
setOptions(RootSrcDir, Options);
@ -405,18 +406,32 @@ collSrcFiles(IsAddPath) ->
_ ->
ignore
end,
Acc#{OneFiles => 1}
setelement(1, Acc, Srcs#{OneFile => MTimeSec})
end;
_ ->
Acc
end
end, #{}),
end, {#{}, #{}, #{}, #{}}),
FunCollAdds =
fun(OneDir, FilesAcc) ->
filelib:fold_files(case is_list(OneDir) of true -> list_to_binary(OneDir); _ ->
OneDir end, ".*\\.(erl|dtl|lfe|ex)$", true, fun(OneFiles, Acc) ->
Acc#{OneFiles => 1} end, FilesAcc)
filelib:fold_files(?IIF(is_list(OneDir), list_to_binary(OneDir), OneDir), ".*\\.(erl|hrl|beam|config|dtl|lfe|ex)$", true,
fun(OneFile, {Srcs, Hrls, Configs, Beams} = Acc) ->
MTimeSec = esUtils:dateTimeToSec(filelib:last_modified(OneFile)),
case filename:extension(OneFile) of
<<".beam">> ->
BeamMod = binary_to_atom(filename:basename(OneFile, <<".beam">>)),
setelement(4, Acc, Beams#{BeamMod => MTimeSec});
<<".config">> ->
setelement(3, Acc, Configs#{OneFile => MTimeSec});
<<".hrl">> ->
setelement(2, Acc, Hrls#{OneFile => MTimeSec});
<<>> ->
Acc;
_ ->
setelement(1, Acc, Srcs#{OneFile => MTimeSec})
end
end, FilesAcc)
end,
lists:foldl(FunCollAdds, CollFiles, AddSrcDirs).
@ -661,11 +676,15 @@ syncLoadModOnAllNodes(Module) ->
[FSync(X) || X <- Nodes],
{ok, NumNodes, Nodes}.
recompileChangeSrcFile([], _SwSyncNode) ->
ok;
recompileChangeSrcFile([File | LeftFile], SwSyncNode) ->
recompileSrcFile(File, SwSyncNode),
recompileChangeSrcFile(LeftFile, SwSyncNode).
recompileChangeSrcFile(Iterator, SwSyncNode) ->
case maps:next(Iterator) of
{File, _V, NextIterator} ->
recompileSrcFile(File, SwSyncNode),
recompileChangeSrcFile(NextIterator, SwSyncNode);
_ ->
ok
end.
erlydtlCompile(SrcFile, Options) ->
F =
@ -811,12 +830,35 @@ recompileSrcFile(SrcFile, SwSyncNode) ->
end
end.
recompileChangeHrlFile([], _SrcFiles, _SwSyncNode) ->
ok;
recompileChangeHrlFile([Hrl | LeftHrl], SrcFiles, SwSyncNode) ->
WhoInclude = whoInclude(Hrl, SrcFiles),
[recompileSrcFile(SrcFile, SwSyncNode) || {SrcFile, _} <- maps:to_list(WhoInclude)],
recompileChangeHrlFile(LeftHrl, SrcFiles, SwSyncNode).
recompileChangeHrlFile([], _SrcFiles, CSrcs) ->
CSrcs;
recompileChangeHrlFile([Hrl | LeftHrl], SrcFiles, CSrcs) ->
NewCSrcs = whoInclude(Hrl, SrcFiles, CSrcs),
recompileChangeHrlFile(LeftHrl, SrcFiles, NewCSrcs).
whoInclude(HrlFile, SrcFiles, CSrcs) ->
HrlFileBaseName = filename:basename(HrlFile),
doMathEveryFile(maps:iterator(SrcFiles), HrlFileBaseName, CSrcs).
doMathEveryFile(Iterator, HrlFileBaseName, CSrcs) ->
case maps:next(Iterator) of
{SrcFile, _V, NextIterator} ->
case file:open(SrcFile, [read, binary]) of
{ok, IoDevice} ->
IsInclude = doMathEveryLine(IoDevice, HrlFileBaseName),
file:close(IoDevice),
case IsInclude of
true ->
doMathEveryFile(NextIterator, HrlFileBaseName, CSrcs#{SrcFile => 1});
_ ->
doMathEveryFile(NextIterator, HrlFileBaseName, CSrcs)
end;
_ ->
doMathEveryFile(NextIterator, HrlFileBaseName, CSrcs)
end;
_ ->
CSrcs
end.
%%
%% whoInclude(HrlFile, SrcFiles) ->
@ -838,20 +880,6 @@ recompileChangeHrlFile([Hrl | LeftHrl], SrcFiles, SwSyncNode) ->
%% isInclude(HrlFile, [_SomeForm | Forms]) ->
%% isInclude(HrlFile, Forms).
whoInclude(HrlFile, SrcFiles) ->
HrlFileBaseName = filename:basename(HrlFile),
Pred =
fun(SrcFile, _) ->
case file:open(SrcFile, [read, binary]) of
{ok, IoDevice} ->
IsInclude = doMathEveryLine(IoDevice, HrlFileBaseName),
file:close(IoDevice),
IsInclude;
_ ->
false
end
end,
maps:filter(Pred, SrcFiles).
doMathEveryLine(IoDevice, HrlFileBaseName) ->
case file:read_line(IoDevice) of
{ok, Data} ->
@ -870,32 +898,65 @@ doMathEveryLine(IoDevice, HrlFileBaseName) ->
false
end.
classifyChangeFile([], Beams, Hrls, Srcs, Configs) ->
{Beams, Hrls, Srcs, Configs};
classifyChangeFile([OneFile | LeftFile], Beams, Hrls, Srcs, Configs) ->
%% IMY-todo filename:absname
classifyChangeFile([], Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams) ->
{Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams};
classifyChangeFile([OneFile | LeftFile], Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams) ->
CurMTimeSec = esUtils:dateTimeToSec(filelib:last_modified(OneFile)),
case filename:extension(OneFile) of
<<".beam">> ->
Module = binary_to_atom(filename:basename(OneFile, <<".beam">>)),
classifyChangeFile(LeftFile, [Module | Beams], Hrls, Srcs, Configs);
<<".hrl">> ->
classifyChangeFile(LeftFile, Beams, [OneFile | Hrls], Srcs, Configs);
BinMod = binary_to_atom(filename:basename(OneFile, <<".beam">>)),
case ColBeams of
#{BinMod := OldMTimeSec} ->
case CurMTimeSec =/= OldMTimeSec andalso CurMTimeSec =/= 0 of
true ->
classifyChangeFile(LeftFile, [BinMod | Beams], Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams#{BinMod := CurMTimeSec});
_ ->
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams)
end;
_ ->
classifyChangeFile(LeftFile, [BinMod | Beams], Hrls, Srcs, Configs, ColSrcs, ColHrls, ColConfigs, ColBeams#{BinMod => CurMTimeSec})
end;
<<".config">> ->
classifyChangeFile(LeftFile, Beams, Hrls, Srcs, [OneFile | Configs]);
AbsFile = filename:absname(OneFile),
case ColConfigs of
#{AbsFile := OldMTimeSec} ->
case CurMTimeSec =/= OldMTimeSec andalso CurMTimeSec =/= 0 of
true ->
classifyChangeFile(LeftFile, Beams, [AbsFile | Configs], Hrls, Srcs, ColSrcs, ColHrls, ColConfigs#{AbsFile := CurMTimeSec}, ColBeams);
_ ->
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams)
end;
_ ->
classifyChangeFile(LeftFile, Beams, [AbsFile | Configs], Hrls, Srcs, ColSrcs, ColHrls, ColConfigs#{AbsFile => CurMTimeSec}, ColBeams)
end;
<<".hrl">> ->
AbsFile = filename:absname(OneFile),
case ColHrls of
#{AbsFile := OldMTimeSec} ->
case CurMTimeSec =/= OldMTimeSec andalso CurMTimeSec =/= 0 of
true ->
classifyChangeFile(LeftFile, Beams, Configs, [AbsFile | Hrls], Srcs, ColSrcs, ColHrls#{AbsFile := CurMTimeSec}, ColConfigs, ColBeams);
_ ->
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams)
end;
_ ->
classifyChangeFile(LeftFile, Beams, Configs, [AbsFile | Hrls], Srcs, ColSrcs, ColHrls#{AbsFile => CurMTimeSec}, ColConfigs, ColBeams)
end;
<<>> ->
classifyChangeFile(LeftFile, Beams, Hrls, Srcs, Configs);
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams);
_ ->
classifyChangeFile(LeftFile, Beams, Hrls, [OneFile | Srcs], Configs)
end.
addNewFile([], SrcFiles) ->
SrcFiles;
addNewFile([OneFile | LeftFile], SrcFiles) ->
case SrcFiles of
#{OneFile := _value} ->
addNewFile(LeftFile, SrcFiles);
_ ->
addNewFile(LeftFile, SrcFiles#{OneFile => 1})
AbsFile = filename:absname(OneFile),
case ColSrcs of
#{AbsFile := OldMTimeSec} ->
case CurMTimeSec =/= OldMTimeSec andalso CurMTimeSec =/= 0 of
true ->
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs#{AbsFile => 1}, ColSrcs#{AbsFile := CurMTimeSec}, ColHrls, ColConfigs, ColBeams);
_ ->
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs, ColSrcs, ColHrls, ColConfigs, ColBeams)
end;
_ ->
classifyChangeFile(LeftFile, Beams, Configs, Hrls, Srcs#{AbsFile => 1}, ColSrcs#{AbsFile => CurMTimeSec}, ColHrls, ColConfigs, ColBeams)
end
end.
fileSyncPath(ExecName) ->
@ -916,6 +977,5 @@ dateTimeToSec(DateTime) ->
DateTime == 0 ->
0;
true ->
localtime_to_universaltime(DateTime, undefined)
erlang:universaltime_to_posixtime(DateTime )
end.

正在加载...
取消
保存