35 Commity

Autor SHA1 Wiadomość Data
  SisMaker d03c32c2f7 Merge branch 'master' of http://192.168.0.88:53000/SisMaker/eGbh 1 rok temu
  SisMaker 8d31462be5 ft: gen_behaviour 错误日志纠正 1 rok temu
  SisMaker 4430bfbbc6 ft: 各种behaviour 默认改成守护模式 1 rok temu
  SisMaker 849d128210 ft: 从otp24.1.2 同步到 Otp26.0.2 1 rok temu
  lijie 2c9159980c ft: gen_ipc.erl 守护模式添加 1 rok temu
  lijie bacb39a05b ft: 修正堆栈 1 rok temu
  lijie e4fcbed817 ft: gen_mpp.erl 守护模式添加 1 rok temu
  SisMaker 46a295c5b9 ft: gen_srv.erl 守护模式添加 1 rok temu
  SisMaker dbe497031a ft: gen_ipc.erl 优化 1 rok temu
  SisMaker 632c9f4e1f ft: 睡眠优化 1 rok temu
  SisMaker b49ad432fc ft: gen_emm.erl 不需要守护模式 1 rok temu
  SisMaker 1a2b6cfe27 ft: 守护模式添加 1 rok temu
  SisMaker 89c6eeb30c ft: 格式化代码 1 rok temu
  SisMaker d35951a966 ft: 给各种行为加上 守护 模式 该模式下try 捕捉到错误后 并不会杀死进程 而是打印日志 1 rok temu
  SisMaker 152c68c24e ft: 编译选项 no_debug_info, deterministic 1 rok temu
  SisMaker 4cad951b8b ft: 去掉编译警告 1 rok temu
  SisMaker 8dee81dc52 dc: 注释 3 lat temu
  SisMaker f8eae6fe2f ft: 完善代码 3 lat temu
  SisMaker 46e32d5091 ft: 代码修改与优化 3 lat temu
  SisMaker 79dcb3ba97 ft: 优化 3 lat temu
  SisMaker 548f566911 ft: 优化undef的情况 3 lat temu
  SisMaker 7c0ef192e4 ft: 部分优化 3 lat temu
  SisMaker 3cc66fcf79 ft: 代码修改 3 lat temu
  SisMaker 3cb782b9d5 ft: gen_mpp添加 3 lat temu
  SisMaker be2c3df38f fx: 问题修复 3 lat temu
  SisMaker 59e76cf36d pf: 修改gen_emm 返回值 3 lat temu
  SisMaker f11e13b28e pf:gen_*不能call自己 3 lat temu
  SisMaker 896ed450c6 pf:gen_*不能call自己 3 lat temu
  SisMaker 03f21e4e78 st: 代码格式化 3 lat temu
  SisMaker c6503ea894 ft: -import代码优化 3 lat temu
  SisMaker 33321b08f1 ft: M F A添加 代码优化 3 lat temu
  SisMaker 86ceaab8e7 ft: call M F A 添加 3 lat temu
  SisMaker b82cfe6594 ft: call M F A 添加 3 lat temu
  SisMaker db9760e704 ft: gen_call:call/3/4 替换 gen:call/3/4 3 lat temu
  SisMaker 44304c6888 ft: 同步gen_xxx 模块到otp24.1.2 3 lat temu
10 zmienionych plików z 3972 dodań i 1320 usunięć
  1. +13
    -2
      README.md
  2. +23
    -0
      include/genGbh.hrl
  3. +1
    -1
      rebar.config
  4. +636
    -354
      src/gen_apu.erl
  5. +134
    -0
      src/gen_call.erl
  6. +235
    -135
      src/gen_emm.erl
  7. +4
    -4
      src/gen_epm.erl
  8. +786
    -466
      src/gen_ipc.erl
  9. +1507
    -0
      src/gen_mpp.erl
  10. +633
    -358
      src/gen_srv.erl

+ 13
- 2
README.md Wyświetl plik

@ -2,7 +2,7 @@
封装与收集各种有用的erlang行为
最初目的是想造个非常统一又通用的行为模式-基于这个想法-封装了gen_ipc行为模块
基于gen_ipc gen_srv 基于Otp23.0.2编写 运行otp版本21+
基于gen_ipc gen_srv 基于Otp26.0.2编写 运行otp版本23.0+
# 简写备注
@ -12,6 +12,7 @@
gen_emm gen_event_management module
gen_tcm gen_tcp_callback_module
gen_apu gen_Automatic_processing_unit
gen_mpp gen_Massively Parallel Processor
# gen_ipc
@ -29,7 +30,17 @@
# gen_srv
出于考虑大部分的行为模式为gen_server, 如果使用gen_ipc大量handle函数会添加一个额外无用的 _ 作为 状态 参数的占位, 可能对于一些追求完美与代码简洁的人来说不可接受,
所以出于该考虑, 基于gen_server结合gen_ipc一些便捷式的定时器封装了gen_srv.
所以出于该考虑, 基于gen_server结合gen_ipc一些便捷式的定时器封装了gen_srv.
# gen_emm
gen_event 重写
# gen_apu
功能与gen_srv一致 只是 call和cast消息 不在调用 handle_call handle_cast函数 而是取消息的第一个参数作为函数名 调用回调模块的这个函数
# gen_mpp
功能与gen_apu一致 只是 不自带定时器相关封装

+ 23
- 0
include/genGbh.hrl Wyświetl plik

@ -0,0 +1,23 @@
-ifndef(genGbh_H).
-define(genGbh_H, true).
-record(gbhOpts, {
daemon = false :: boolean() %% try catch handleError
}).
-ifdef(debug_gbh).
%% debug
-define(NOT_DEBUG, []).
-define(SYS_DEBUG(Debug, Name, Msg),
case Debug of
?NOT_DEBUG ->
ok;
_ ->
sys:handle_debug(Debug, fun print_event/3, Name, Msg)
end).
-else.
-define(SYS_DEBUG(Debug, Name, Msg), ok).
-endif.
-endif.

+ 1
- 1
rebar.config Wyświetl plik

@ -1 +1 @@
{erl_opts, [no_debug_info]}.
{erl_opts, [no_debug_info, {i, "include"}, deterministic]}.

+ 636
- 354
src/gen_apu.erl
Plik diff jest za duży
Wyświetl plik


+ 134
- 0
src/gen_call.erl Wyświetl plik

@ -0,0 +1,134 @@
-module(gen_call).
-export([gcall/3, gcall/4, greply/2, try_greply/2]).
-define(default_timeout, 5000).
%% We trust the arguments to be correct, i.e
%% Process is either a local or remote pid,
%% or a {Name, Node} tuple (of atoms) and in this
%% case this node (node()) _is_ distributed and Node =/= node().
-define(get_node(Process), case Process of {_S, N} -> N; _ -> node(Process) end).
gcall(Process, Label, Request) ->
gcall(Process, Label, Request, ?default_timeout).
gcall(Process, Label, Request, Timeout) ->
%%-----------------------------------------------------------------
%% Map different specifications of a process to either Pid or
%% {Name,Node}. Execute the given Fun with the process as only
%% argument.
%% -----------------------------------------------------------------
case where(Process) of
undefined ->
exit(noproc);
PidOrNameNode ->
%Node = ?get_node(PidOrNameNode),
try do_call(PidOrNameNode, Label, Request, Timeout)
catch
exit:{nodedown, _Node} ->
%% A nodedown not yet detected by global, pretend that it was.
exit(noproc)
end
end.
-dialyzer({no_improper_lists, do_call/4}).
do_call(Process, Label, Request, Timeout) ->
CurNode = node(),
case ?get_node(Process) of
CurNode ->
Mref = erlang:monitor(process, Process),
%% Local without timeout; no need to use alias since we unconditionally
%% will wait for either a reply or a down message which corresponds to
%% the process being terminated (as opposed to 'noconnection')...
case self() of
Process ->
exit(calling_self);
_ ->
Process ! {Label, {self(), Mref}, Request}
end,
receive
{Mref, Reply} ->
erlang:demonitor(Mref, [flush]),
{ok, Reply};
{'DOWN', Mref, _, _, Reason} ->
exit(Reason)
after Timeout ->
erlang:demonitor(Mref, [flush]),
receive
{[alias | Mref], Reply} ->
{ok, Reply}
after 0 ->
exit(timeout)
end
end;
_PNode ->
Mref = erlang:monitor(process, Process, [{alias, demonitor}]),
Tag = [alias | Mref],
%% OTP-24:
%% Using alias to prevent responses after 'noconnection' and timeouts.
%% We however still may call nodes responding via process identifier, so
%% we still use 'noconnect' on send in order to try to send on the
%% monitored connection, and not trigger a new auto-connect.
%%
erlang:send(Process, {Label, {self(), Tag}, Request}, [noconnect]),
receive
{[alias | Mref], Reply} ->
erlang:demonitor(Mref, [flush]),
{ok, Reply};
{'DOWN', Mref, _, _, noconnection} ->
exit({nodedown, _PNode});
{'DOWN', Mref, _, _, Reason} ->
exit(Reason)
after Timeout ->
erlang:demonitor(Mref, [flush]),
receive
{[alias | Mref], Reply} ->
{ok, Reply}
after 0 ->
exit(timeout)
end
end
end.
where({global, Name}) -> global:whereis_name(Name);
where({local, Name}) -> whereis(Name);
where({via, Module, Name}) -> Module:whereis_name(Name);
where({Name, Node} = Process) ->
CurNode = node(),
case CurNode of
Node ->
whereis(Name);
nonode@nohost ->
exit({nodedown, Node});
_ when is_atom(Name), is_atom(Node) ->
Process;
_ ->
undefined
end;
where(Name) ->
if
is_pid(Name) ->
Name;
is_atom(Name) ->
whereis(Name);
true ->
undefined
end.
%%
%% Send a reply to the client.
%%
greply({_To, [alias | Alias] = Tag}, Reply) when is_reference(Alias) ->
Alias ! {Tag, Reply}, ok;
greply({_To, [[alias | Alias] | _] = Tag}, Reply) when is_reference(Alias) ->
Alias ! {Tag, Reply}, ok;
greply({To, Tag}, Reply) ->
try To ! {Tag, Reply}, ok catch _:_ -> ok end.
try_greply(false, _Msg) ->
ignore;
try_greply(From, Reply) ->
greply(From, Reply).

+ 235
- 135
src/gen_emm.erl Wyświetl plik

@ -4,8 +4,10 @@
-compile({inline_size, 128}).
-include_lib("kernel/include/logger.hrl").
-include("genGbh.hrl").
-import(maps, [iterator/1, next/1]).
-import(gen_call, [gcall/3, gcall/4, greply/2, try_greply/2]).
-export([
%% API for gen_emm
@ -14,7 +16,13 @@
, stop/1, stop/3
, call/3, call/4
, send/3
, send_request/3, wait_response/2, receive_response/2, check_response/2
, send_request/3, send_request/5
, wait_response/2, receive_response/2, check_response/2
, wait_response/3, receive_response/3, check_response/3
, reqids_new/0, reqids_size/1
, reqids_add/3, reqids_to_list/1
, info_notify/2, call_notify/2
, add_epm/3, add_sup_epm/3, del_epm/3
, swap_epm/3, swap_sup_epm/3
@ -35,21 +43,11 @@
, wakeupFromHib/5
%% logger callback
, format_log/1, format_log/2
, format_log/1, format_log/2, print_event/3
]).
-define(STACKTRACE(), element(2, erlang:process_info(self(), current_stacktrace))).
%% debug
-define(NOT_DEBUG, []).
-define(SYS_DEBUG(Debug, Name, Msg),
case Debug of
?NOT_DEBUG ->
Debug;
_ ->
sys:handle_debug(Debug, fun print_event/3, Name, Msg)
end).
-type epmHandler() ::
atom() |
{atom(), term()}.
@ -105,7 +103,9 @@
{'error', term()}.
-type from() :: {To :: pid(), Tag :: term()}.
-type requestId() :: term().
-type request_id() :: gen:request_id().
-type request_id_collection() :: gen:request_id_collection().
-type response_timeout() :: timeout() | {abs, integer()}.
-record(epmHer, {
epmId = undefined :: term(),
@ -122,8 +122,8 @@
-callback handleEvent(Event :: term(), State :: term()) ->
kpS |
removeEpm |
{ok, NewState :: term()} |
{ok, NewState :: term(), hibernate} |
{noreply, NewState :: term()} |
{noreply, NewState :: term(), hibernate} |
{swapEpm, NewState :: term(), Args1 :: term(), NewHandler :: epmHandler(), Args2 :: term()}.
-callback handleCall(Request :: term(), State :: term()) ->
@ -136,8 +136,8 @@
-callback handleInfo(Info :: term(), State :: term()) ->
kpS |
removeEpm |
{ok, NewState :: term()} |
{ok, NewState :: term(), hibernate} |
{noreply, NewState :: term()} |
{noreply, NewState :: term(), hibernate} |
{swapEpm, NewState :: term(), Args1 :: term(), NewHandler :: epmHandler(), Args2 :: term()}.
-callback terminate(Args :: terminateArgs(), State :: term()) ->
@ -264,34 +264,186 @@ call(EpmSrv, EpmHandler, Query, Timeout) ->
send(EpmSrv, EpmHandler, Msg) ->
epmRequest(EpmSrv, {'$epm_info', EpmHandler, Msg}).
-spec send_request(serverRef(), epmHandler(), term()) -> requestId().
send_request(EpmSrv, EpmHandler, Query) ->
gen:send_request(EpmSrv, '$epm_call', {'$epmCall', EpmHandler, Query}).
-spec send_request(EventMgrRef::serverRef, Handler::epmHandler(), Request::term()) ->
ReqId::request_id().
send_request(M, Handler, Request) ->
try
gen:send_request(M, '$epm_call', {'$epmCall', Handler, Request})
catch
error:badarg ->
error(badarg, [M, Handler, Request])
end.
-spec send_request(EventMgrRef::serverRef,
Handler::epmHandler(),
Request::term(),
Label::term(),
ReqIdCollection::request_id_collection()) ->
NewReqIdCollection::request_id_collection().
send_request(M, Handler, Request, Label, ReqIdCol) ->
try
gen:send_request(M, '$epm_call', {'$epmCall', Handler, Request}, Label, ReqIdCol)
catch
error:badarg ->
error(badarg, [M, Handler, Request, Label, ReqIdCol])
end.
-spec wait_response(ReqId, WaitTime) -> Result when
ReqId :: request_id(),
WaitTime :: response_timeout(),
Response :: {reply, Reply::term()}
| {error, {Reason::term(), serverRef}},
Result :: Response | 'timeout'.
-spec wait_response(RequestId :: requestId(), timeout()) -> {reply, Reply :: term()} | 'timeout' | {error, {Reason :: term(), serverRef()}}.
wait_response(RequestId, Timeout) ->
case gen:wait_response(RequestId, Timeout) of
wait_response(ReqId, WaitTime) ->
try gen:wait_response(ReqId, WaitTime) of
{reply, {error, _} = Err} -> Err;
Return -> Return
catch
error:badarg ->
error(badarg, [ReqId, WaitTime])
end.
-spec wait_response(ReqIdCollection, WaitTime, Delete) -> Result when
ReqIdCollection :: request_id_collection(),
WaitTime :: response_timeout(),
Delete :: boolean(),
Response :: {reply, Reply::term()} |
{error, {Reason::term(), serverRef}},
Result :: {Response,
Label::term(),
NewReqIdCollection::request_id_collection()} |
'no_request' |
'timeout'.
wait_response(ReqIdCol, WaitTime, Delete) ->
try gen:wait_response(ReqIdCol, WaitTime, Delete) of
{{reply, {error, _} = Err}, Label, NewReqIdCol} ->
{Err, Label, NewReqIdCol};
Return ->
Return
catch
error:badarg ->
error(badarg, [ReqIdCol, WaitTime, Delete])
end.
-spec receive_response(RequestId::requestId(), timeout()) -> {reply, Reply::term()} | 'timeout' | {error, {Reason::term(), serverRef()}}.
receive_response(RequestId, Timeout) ->
case gen:receive_response(RequestId, Timeout) of
-spec receive_response(ReqId, Timeout) -> Result when
ReqId :: request_id(),
Timeout :: response_timeout(),
Response :: {reply, Reply::term()} |
{error, {Reason::term(), serverRef}},
Result :: Response | 'timeout'.
receive_response(ReqId, Timeout) ->
try gen:receive_response(ReqId, Timeout) of
{reply, {error, _} = Err} -> Err;
Return -> Return
catch
error:badarg ->
error(badarg, [ReqId, Timeout])
end.
-spec receive_response(ReqIdCollection, Timeout, Delete) -> Result when
ReqIdCollection :: request_id_collection(),
Timeout :: response_timeout(),
Delete :: boolean(),
Response :: {reply, Reply::term()} |
{error, {Reason::term(), serverRef}},
Result :: {Response,
Label::term(),
NewReqIdCollection::request_id_collection()} |
'no_request' |
'timeout'.
receive_response(ReqIdCol, Timeout, Delete) ->
try gen:receive_response(ReqIdCol, Timeout, Delete) of
{{reply, {error, _} = Err}, Label, NewReqIdCol} ->
{Err, Label, NewReqIdCol};
Return ->
Return
catch
error:badarg ->
error(badarg, [ReqIdCol, Timeout, Delete])
end.
-spec check_response(Msg :: term(), RequestId :: requestId()) ->
{reply, Reply :: term()} | 'no_reply' | {error, {Reason :: term(), serverRef()}}.
check_response(Msg, RequestId) ->
case gen:check_response(Msg, RequestId) of
-spec check_response(Msg, ReqId) -> Result when
Msg :: term(),
ReqId :: request_id(),
Response :: {reply, Reply::term()} |
{error, {Reason::term(), serverRef}},
Result :: Response | 'no_reply'.
check_response(Msg, ReqId) ->
try gen:check_response(Msg, ReqId) of
{reply, {error, _} = Err} -> Err;
Return -> Return
catch
error:badarg ->
error(badarg, [Msg, ReqId])
end.
-spec check_response(Msg, ReqIdCollection, Delete) -> Result when
Msg :: term(),
ReqIdCollection :: request_id_collection(),
Delete :: boolean(),
Response :: {reply, Reply::term()} |
{error, {Reason::term(), serverRef}},
Result :: {Response,
Label::term(),
NewReqIdCollection::request_id_collection()} |
'no_request' |
'no_reply'.
check_response(Msg, ReqIdCol, Delete) ->
try gen:check_response(Msg, ReqIdCol, Delete) of
{{reply, {error, _} = Err}, Label, NewReqIdCol} ->
{Err, Label, NewReqIdCol};
Return ->
Return
catch
error:badarg ->
error(badarg, [Msg, ReqIdCol, Delete])
end.
-spec reqids_new() ->
NewReqIdCollection::request_id_collection().
reqids_new() ->
gen:reqids_new().
-spec reqids_size(ReqIdCollection::request_id_collection()) ->
non_neg_integer().
reqids_size(ReqIdCollection) ->
try
gen:reqids_size(ReqIdCollection)
catch
error:badarg -> error(badarg, [ReqIdCollection])
end.
-spec reqids_add(ReqId::request_id(), Label::term(),
ReqIdCollection::request_id_collection()) ->
NewReqIdCollection::request_id_collection().
reqids_add(ReqId, Label, ReqIdCollection) ->
try
gen:reqids_add(ReqId, Label, ReqIdCollection)
catch
error:badarg -> error(badarg, [ReqId, Label, ReqIdCollection])
end.
-spec reqids_to_list(ReqIdCollection::request_id_collection()) ->
[{ReqId::request_id(), Label::term()}].
reqids_to_list(ReqIdCollection) ->
try
gen:reqids_to_list(ReqIdCollection)
catch
error:badarg -> error(badarg, [ReqIdCollection])
end.
epmRpc(EpmSrv, Cmd) ->
try gen:call(EpmSrv, '$epm_call', Cmd, infinity) of
try gcall(EpmSrv, '$epm_call', Cmd, infinity) of
{ok, Reply} ->
Reply
catch Class:Reason ->
@ -299,7 +451,7 @@ epmRpc(EpmSrv, Cmd) ->
end.
epmRpc(EpmSrv, Cmd, Timeout) ->
try gen:call(EpmSrv, '$epm_call', Cmd, Timeout) of
try gcall(EpmSrv, '$epm_call', Cmd, Timeout) of
{ok, Reply} ->
Reply
catch Class:Reason ->
@ -345,65 +497,65 @@ receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, IsHib) ->
end.
epmCallMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, From, Request) ->
NewDebug = ?SYS_DEBUG(Debug, ServerName, {call, From, Request}),
?SYS_DEBUG(Debug, ServerName, {call, From, Request}),
case Request of
'$which_handlers' ->
reply(From, maps:keys(EpmHers)),
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, NewDebug, false);
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, false);
{'$addEpm', EpmHandler, Args} ->
{Reply, NewEpmHers, IsHib} = doAddEpm(EpmHers, EpmHandler, Args, undefined),
reply(From, Reply),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
{'$addSupEpm', EpmHandler, Args, EpmSup} ->
{Reply, NewEpmHers, IsHib} = doAddSupEpm(EpmHers, EpmHandler, Args, EpmSup),
reply(From, Reply),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
{'$delEpm', EpmHandler, Args} ->
{Reply, NewEpmHers} = doDelEpm(EpmHers, EpmHandler, Args),
reply(From, Reply),
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false);
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false);
{'$swapEpm', EpmId1, Args1, EpmId2, Args2} ->
{Reply, NewEpmHers, IsHib} = doSwapEpm(EpmHers, EpmId1, Args1, EpmId2, Args2),
reply(From, Reply),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
{'$swapSupEpm', EpmId1, Args1, EpmId2, Args2, SupPid} ->
{Reply, NewEpmHers, IsHib} = doSwapSupEpm(EpmHers, EpmId1, Args1, EpmId2, Args2, SupPid),
reply(From, Reply),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
{'$syncNotify', Event} ->
{NewEpmHers, IsHib} = doNotify(EpmHers, handleEvent, Event, false),
reply(From, ok),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
{'$epmCall', EpmHandler, Query} ->
case doEpmHandle(EpmHers, EpmHandler, handleCall, Query, From) of
{NewEpmHers, IsHib} ->
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
NewEpmHers ->
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false)
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false)
end
end.
epmInfoMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, CmdOrEmpHandler, Event) ->
NewDebug = ?SYS_DEBUG(Debug, ServerName, {info, CmdOrEmpHandler, Event}),
?SYS_DEBUG(Debug, ServerName, {info, CmdOrEmpHandler, Event}),
case CmdOrEmpHandler of
'$infoNotify' ->
{NewEpmHers, IsHib} = doNotify(EpmHers, handleEvent, Event, false),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
EpmHandler ->
case doEpmHandle(EpmHers, EpmHandler, handleInfo, Event, false) of
{NewEpmHers, IsHib} ->
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib);
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib);
NewEpmHers ->
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false)
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false)
end
end.
handleMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, Msg) ->
NewDebug = ?SYS_DEBUG(Debug, ServerName, {in, Msg}),
?SYS_DEBUG(Debug, ServerName, {in, Msg}),
case Msg of
{'EXIT', From, Reason} ->
NewEpmHers = epmStopOne(From, EpmHers, Reason),
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false);
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false);
{_From, Tag, stop} ->
try terminate_server(normal, Parent, ServerName, EpmHers)
after
@ -411,13 +563,13 @@ handleMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, Msg) ->
end;
{_From, Tag, get_modules} ->
reply(Tag, get_modules(EpmHers)),
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, NewDebug, false);
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, false);
{_From, Tag, which_handlers} ->
reply(Tag, maps:keys(EpmHers)),
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, NewDebug, false);
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, false);
_ ->
{NewEpmHers, IsHib} = doNotify(EpmHers, handleInfo, Msg, false),
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib)
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib)
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -503,10 +655,10 @@ doSwapSupEpm(EpmHers, EpmId1, Args1, EpmMId, Args2, EpmSup) ->
end.
doNotify(EpmHers, Func, Event, _Form) ->
allNotify(maps:iterator(EpmHers), Func, Event, false, EpmHers, false).
allNotify(iterator(EpmHers), Func, Event, false, EpmHers, false).
allNotify(Iterator, Func, Event, From, TemEpmHers, IsHib) ->
case maps:next(Iterator) of
case next(Iterator) of
{K, _V, NextIterator} ->
case doEpmHandle(TemEpmHers, K, Func, Event, From) of
{NewEpmHers, NewIsHib} ->
@ -527,12 +679,12 @@ doEpmHandle(EpmHers, EpmId, Func, Event, From) ->
catch
throw:Ret ->
handleEpmCR(Ret, EpmHers, EpmId, EpmHer, Event, From);
C:R:S ->
epmTerminate(EpmHer, {error, {C, R, S}}, Event, crash),
Class:Reason:Strace ->
epmTerminate(EpmHer, {error, {Class, Reason, Strace}}, Event, crash),
maps:remove(EpmId, EpmHers)
end;
_ ->
try_reply(From, {error, bad_module}),
try_greply(From, {error, bad_module}),
EpmHers
end.
@ -550,10 +702,10 @@ handleEpmCR(Result, EpmHers, EpmId, EpmHer, Event, From) ->
case Result of
kpS ->
EpmHers;
{ok, NewEpmS} ->
{noreply, NewEpmS} ->
MewEpmHer = setelement(#epmHer.epmS, EpmHer, NewEpmS),
EpmHers#{EpmId := MewEpmHer};
{ok, NewEpmS, hibernate} ->
{noreply, NewEpmS, hibernate} ->
MewEpmHer = setelement(#epmHer.epmS, EpmHer, NewEpmS),
{EpmHers#{EpmId := MewEpmHer}, true};
{swapEpm, NewEpmS, Args1, EpmMId, Args2} ->
@ -600,7 +752,7 @@ handleEpmCR(Result, EpmHers, EpmId, EpmHer, Event, From) ->
MewEpmHer = setelement(#epmHer.epmS, EpmHer, NewEpmS),
{EpmHers#{EpmId := MewEpmHer}, true};
Other ->
epmTerminate(EpmHer, {error, Other}, Event, crash),
epmTerminate(EpmHer, {error, {bad_ret, Other}}, Event, crash),
maps:remove(EpmId, EpmHers)
end.
@ -636,14 +788,14 @@ report_error(#epmHer{epmId = EpmId, epmM = EpmM}, Reason, State, LastIn) ->
#{
domain => [otp],
report_cb => fun gen_emm:format_log/2,
error_logger => #{tag => error, report_cb => fun gen_event:format_log/1}
error_logger => #{tag => error, report_cb => fun gen_emm:format_log/1}
}).
epmStopAll(EpmHers) ->
forStopAll(maps:iterator(EpmHers)).
forStopAll(iterator(EpmHers)).
forStopAll(Iterator) ->
case maps:next(Iterator) of
case next(Iterator) of
{_K, V, NextIterator} ->
epmTerminate(V, stop, stop, shutdown),
case element(#epmHer.epmSup, V) of
@ -658,10 +810,10 @@ forStopAll(Iterator) ->
end.
epmStopOne(ExitEmpSup, EpmHers, Reason) ->
forStopOne(maps:iterator(EpmHers), ExitEmpSup, Reason, EpmHers).
forStopOne(iterator(EpmHers), ExitEmpSup, Reason, EpmHers).
forStopOne(Iterator, ExitEmpSup, Reason, TemEpmHers) ->
case maps:next(Iterator) of
case next(Iterator) of
{K, V, NextIterator} ->
case element(#epmHer.epmSup, V) =:= ExitEmpSup of
true ->
@ -685,28 +837,10 @@ epmTerminate(#epmHer{epmM = EpmM, epmS = State} = EpmHer, Args, LastIn, Reason)
ok
end.
-compile({inline, [reply/2]}).
-spec reply(From :: from(), Reply :: term()) -> ok.
reply({_To, [alias|Alias] = Tag}, Reply) ->
Alias ! {Tag, Reply},
ok;
reply({To, Ref}, Msg) ->
try To ! {Ref, Msg},
ok
catch _:_ ->
ok
end.
try_reply(false, _Msg) ->
ignore;
try_reply({_To, [alias|Alias] = Tag}, Reply) ->
Alias ! {Tag, Reply},
ok;
try_reply({To, Ref}, Msg) ->
try To ! {Ref, Msg},
ok
catch _:_ ->
ok
end.
reply(From, Reply) ->
greply(From, Reply).
terminate_server(Reason, _Parent, _ServerName, EpmHers) ->
epmStopAll(EpmHers),
@ -727,11 +861,11 @@ system_terminate(Reason, Parent, _Debug, {ServerName, _HibernateAfterTimeout, Ep
%% which module should be changed.
%%-----------------------------------------------------------------
system_code_change({ServerName, HibernateAfterTimeout, EpmHers, IsHib}, Module, OldVsn, Extra) ->
NewEpmHers = forCodeChange(maps:iterator(EpmHers), Module, OldVsn, Extra, EpmHers),
NewEpmHers = forCodeChange(iterator(EpmHers), Module, OldVsn, Extra, EpmHers),
{ok, {ServerName, HibernateAfterTimeout, NewEpmHers, IsHib}}.
forCodeChange(Iterator, CModule, OldVsn, Extra, TemEpmHers) ->
case maps:next(Iterator) of
case next(Iterator) of
{K, #epmHer{epmM = Module, epmS = EpmS} = V, NextIterator} when Module =:= CModule ->
{ok, NewEpmS} = Module:code_change(OldVsn, EpmS, Extra),
forCodeChange(NextIterator, CModule, OldVsn, Extra, TemEpmHers#{K := V#epmHer{epmS = NewEpmS}});
@ -742,10 +876,10 @@ forCodeChange(Iterator, CModule, OldVsn, Extra, TemEpmHers) ->
end.
system_get_state({_ServerName, _HibernateAfterTimeout, EpmHers, _Hib}) ->
{ok, forGetState(maps:iterator(EpmHers), [])}.
{ok, forGetState(iterator(EpmHers), [])}.
forGetState(Iterator, Acc) ->
case maps:next(Iterator) of
case next(Iterator) of
{_K, #epmHer{epmId = EpmId, epmM = Module, epmS = EpmS}, NextIterator} ->
forGetState(NextIterator, [{Module, EpmId, EpmS} | Acc]);
_ ->
@ -753,11 +887,11 @@ forGetState(Iterator, Acc) ->
end.
system_replace_state(StateFun, {ServerName, HibernateAfterTimeout, EpmHers, IsHib}) ->
{NewEpmHers, NStates} = forReplaceState(maps:iterator(EpmHers), StateFun, EpmHers, []),
{NewEpmHers, NStates} = forReplaceState(iterator(EpmHers), StateFun, EpmHers, []),
{ok, NStates, {ServerName, HibernateAfterTimeout, NewEpmHers, IsHib}}.
forReplaceState(Iterator, StateFun, TemEpmHers, NStates) ->
case maps:next(Iterator) of
case next(Iterator) of
{K, #epmHer{epmId = EpmId, epmM = Module, epmS = EpmS} = V, NextIterator} ->
NState = {_, _, NewEpmS} = StateFun({Module, EpmId, EpmS}),
forReplaceState(NextIterator, StateFun, TemEpmHers#{K := V#epmHer{epmS = NewEpmS}}, [NState | NStates]);
@ -798,7 +932,7 @@ format_log(Report) ->
limit_report(Report, unlimited) ->
Report;
limit_report(#{label := {gen_event, terminate},
limit_report(#{label := {gen_emm, epm_terminate},
last_message := LastIn,
state := State,
reason := Reason} = Report,
@ -807,9 +941,7 @@ limit_report(#{label := {gen_event, terminate},
last_message => io_lib:limit_term(LastIn, Depth),
state => io_lib:limit_term(State, Depth),
reason => io_lib:limit_term(Reason, Depth)
};
limit_report(#{label := {gen_event, no_handle_info}, message := Msg} = Report, Depth) ->
Report#{message => io_lib:limit_term(Msg, Depth)}.
}.
%% format_log/2 is the report callback for any Logger handler, except
%% error_logger.
@ -831,7 +963,7 @@ format_log(Report, FormatOpts0) ->
{Format, Args} = format_log_single(Report, FormatOpts),
io_lib:format(Format, Args, IoOpts).
format_log_single(#{label := {gen_event, terminate},
format_log_single(#{label := {gen_emm, epm_terminate},
handler := Handler,
name := SName,
last_message := LastIn,
@ -851,25 +983,9 @@ format_log_single(#{label := {gen_event, terminate},
[Handler, Depth, SName, Depth, Reason1, Depth,
LastIn, Depth, State, Depth]
end,
{Format1, Args1};
format_log_single(#{label := {gen_event, no_handle_info},
module := Mod,
message := Msg},
#{single_line := true, depth := Depth} = FormatOpts) ->
P = p(FormatOpts),
Format = lists:append(["Undefined handle_info in ", P, ". Unhandled message: ", P, "."]),
Args =
case Depth of
unlimited ->
[Mod, Msg];
_ ->
[Mod, Depth, Msg, Depth]
end,
{Format, Args};
format_log_single(Report, FormatOpts) ->
format_log_multi(Report, FormatOpts).
{Format1, Args1}.
format_log_multi(#{label := {gen_event, terminate},
format_log_multi(#{label := {gen_emm, epm_terminate},
handler := Handler,
name := SName,
last_message := LastIn,
@ -879,7 +995,7 @@ format_log_multi(#{label := {gen_event, terminate},
Reason1 = fix_reason(Reason),
P = p(FormatOpts),
Format =
lists:append(["** gen_event handler ", P, " crashed.\n",
lists:append(["** gen_emm handler ", P, " crashed.\n",
"** Was installed in ", P, "\n",
"** Last event was: ", P, "\n",
"** When handler state == ", P, "\n",
@ -891,22 +1007,6 @@ format_log_multi(#{label := {gen_event, terminate},
_ ->
[Handler, Depth, SName, Depth, LastIn, Depth, State, Depth, Reason1, Depth]
end,
{Format, Args};
format_log_multi(#{label := {gen_event, no_handle_info},
module := Mod,
message := Msg},
#{depth := Depth} = FormatOpts) ->
P = p(FormatOpts),
Format =
"** Undefined handle_info in ~p\n"
"** Unhandled message: " ++ P ++ "\n",
Args =
case Depth of
unlimited ->
[Mod, Msg];
_ ->
[Mod, Msg, Depth]
end,
{Format, Args}.
fix_reason({'EXIT', {undef, [{M, F, A, _L} | _] = MFAs} = Reason}) ->
@ -942,10 +1042,10 @@ mod(_) -> "t".
%% Message from the release_handler.
%% The list of modules got to be a set, i.e. no duplicate elements!
get_modules(EpmHers) ->
allMods(maps:iterator(EpmHers), []).
allMods(iterator(EpmHers), []).
allMods(Iterator, Acc) ->
case maps:next(Iterator) of
case next(Iterator) of
{_K, V, NextIterator} ->
allMods(NextIterator, [element(#epmHer.epmM, V) | Acc]);
_ ->
@ -958,11 +1058,11 @@ allMods(Iterator, Acc) ->
format_status(Opt, StatusData) ->
[PDict, SysState, Parent, _Debug, {ServerName, _HibernateAfterTimeout, EpmHers, _IsHib}] = StatusData,
Header = gen:format_status_header("Status for gen_emm handler", ServerName),
FmtMSL = allStateStatus(maps:iterator(EpmHers), Opt, PDict, []),
FmtMSL = allStateStatus(iterator(EpmHers), Opt, PDict, []),
[{header, Header}, {data, [{"Status", SysState}, {"Parent", Parent}]}, {items, {"Installed handlers", FmtMSL}}].
allStateStatus(Iterator, Opt, PDict, EpmHers) ->
case maps:next(Iterator) of
case next(Iterator) of
{_K, #epmHer{epmM = Module, epmS = EpmS} = V, NextIterator} ->
NewEpmS = format_status(Opt, Module, PDict, EpmS),
allStateStatus(NextIterator, Opt, PDict, [V#epmHer{epmS = NewEpmS} | EpmHers]);

+ 4
- 4
src/gen_epm.erl Wyświetl plik

@ -16,8 +16,8 @@
-callback handleEvent(Event :: term(), State :: term()) ->
kpS |
removeEpm |
{ok, NewState :: term()} |
{ok, NewState :: term(), hibernate} |
{noreply, NewState :: term()} |
{noreply, NewState :: term(), hibernate} |
{swapEpm, NewState :: term(), Args1 :: term(), NewHandler :: gen_ipc:epmHandler(), Args2 :: term()}.
-callback handleCall(Request :: term(), State :: term()) ->
@ -30,8 +30,8 @@
-callback handleInfo(Info :: term(), State :: term()) ->
kpS |
removeEpm |
{ok, NewState :: term()} |
{ok, NewState :: term(), hibernate} |
{noreply, NewState :: term()} |
{noreply, NewState :: term(), hibernate} |
{swapEpm, NewState :: term(), Args1 :: term(), NewHandler :: gen_ipc:epmHandler(), Args2 :: term()}.
-callback terminate(Args :: terminateArgs(), State :: term()) -> term().

+ 786
- 466
src/gen_ipc.erl
Plik diff jest za duży
Wyświetl plik


+ 1507
- 0
src/gen_mpp.erl
Plik diff jest za duży
Wyświetl plik


+ 633
- 358
src/gen_srv.erl
Plik diff jest za duży
Wyświetl plik


Ładowanie…
Anuluj
Zapisz