From 44304c688865047122d565071506053b05b047b6 Mon Sep 17 00:00:00 2001 From: SisMaker <1713699517@qq.com> Date: Fri, 22 Oct 2021 15:06:46 +0800 Subject: [PATCH] =?UTF-8?q?ft:=20=E5=90=8C=E6=AD=A5gen=5Fxxx=20=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E5=88=B0otp24.1.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +++++++++-- src/gen_apu.erl | 19 ++++++++++++------- src/gen_ipc.erl | 9 +++++++++ src/gen_srv.erl | 15 ++++++++++----- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 62500cf..1f0f1b9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 封装与收集各种有用的erlang行为 最初目的是想造个非常统一又通用的行为模式-基于这个想法-封装了gen_ipc行为模块 - 基于gen_ipc gen_srv 基于Otp23.0.2编写 运行otp版本21+ + 基于gen_ipc gen_srv 基于Otp24.1.2编写 运行otp版本23.0+ # 简写备注 @@ -29,7 +29,14 @@ # 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函数 而是取消息的第一个参数作为函数名 调用回调模块的这个函数 + diff --git a/src/gen_apu.erl b/src/gen_apu.erl index 8547d6f..ea75602 100644 --- a/src/gen_apu.erl +++ b/src/gen_apu.erl @@ -416,6 +416,15 @@ multi_call(Nodes, Name, Request, infinity) -> multi_call(Nodes, Name, Request, Timeout) when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 -> do_multi_call(Nodes, Name, Request, Timeout). +do_multi_call([Node], Name, Req, infinity) when Node =:= node() -> + % Special case when multi_call is used with local node only. + % In that case we can leverage the benefit of recv_mark optimisation + % existing in simple gen:call. + try gen:call(Name, '$gen_call', Req, infinity) of + {ok, Res} -> {[{Node, Res}],[]} + catch exit:_ -> + {[], [Node]} + end; do_multi_call(Nodes, Name, Request, infinity) -> Tag = make_ref(), Monitors = send_nodes(Nodes, Name, Tag, Request), @@ -718,7 +727,7 @@ matchCallMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurStat FunName = element(1, Request), Module:FunName(Request, CurState, From); _ -> - Module:Request(CurState, From) + Module:Request(Request, CurState, From) end of Result -> @@ -738,7 +747,7 @@ matchCastMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurStat FunName = element(1, Cast), Module:FunName(Cast, CurState); _ -> - Module:Cast(CurState) + Module:Cast(Cast, CurState) end of Result -> @@ -1150,11 +1159,7 @@ format_log_multi(#{label := {gen_apu, terminate}, Args = case Depth of unlimited -> - [Name, Msg, State, Reason1] ++ - case Log of - [] -> []; - _ -> Log - end ++ ClientArgs; + [Name, Msg, State, Reason1] ++ Log ++ ClientArgs; _ -> [Name, Depth, Msg, Depth, State, Depth, Reason1, Depth] ++ case Log of diff --git a/src/gen_ipc.erl b/src/gen_ipc.erl index 4a8983d..87a3119 100644 --- a/src/gen_ipc.erl +++ b/src/gen_ipc.erl @@ -574,6 +574,15 @@ multi_call(Nodes, Name, Request, infinity) -> multi_call(Nodes, Name, Request, Timeout) when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 -> do_multi_call(Nodes, Name, Request, Timeout). +do_multi_call([Node], Name, Req, infinity) when Node =:= node() -> + % Special case when multi_call is used with local node only. + % In that case we can leverage the benefit of recv_mark optimisation + % existing in simple gen:call. + try gen:call(Name, '$gen_call', Req, infinity) of + {ok, Res} -> {[{Node, Res}],[]} + catch exit:_ -> + {[], [Node]} + end; do_multi_call(Nodes, Name, Request, infinity) -> Tag = make_ref(), Monitors = send_nodes(Nodes, Name, Tag, Request), diff --git a/src/gen_srv.erl b/src/gen_srv.erl index 918c10b..441626a 100644 --- a/src/gen_srv.erl +++ b/src/gen_srv.erl @@ -412,6 +412,15 @@ multi_call(Nodes, Name, Request, infinity) -> multi_call(Nodes, Name, Request, Timeout) when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 -> do_multi_call(Nodes, Name, Request, Timeout). +do_multi_call([Node], Name, Req, infinity) when Node =:= node() -> + % Special case when multi_call is used with local node only. + % In that case we can leverage the benefit of recv_mark optimisation + % existing in simple gen:call. + try gen:call(Name, '$gen_call', Req, infinity) of + {ok, Res} -> {[{Node, Res}],[]} + catch exit:_ -> + {[], [Node]} + end; do_multi_call(Nodes, Name, Request, infinity) -> Tag = make_ref(), Monitors = send_nodes(Nodes, Name, Tag, Request), @@ -1130,11 +1139,7 @@ format_log_multi(#{label := {gen_srv, terminate}, Args = case Depth of unlimited -> - [Name, Msg, State, Reason1] ++ - case Log of - [] -> []; - _ -> Log - end ++ ClientArgs; + [Name, Msg, State, Reason1] ++ Log ++ ClientArgs; _ -> [Name, Depth, Msg, Depth, State, Depth, Reason1, Depth] ++ case Log of