From bdd5b2997f83bee2b8d4556717c51402f60c98b5 Mon Sep 17 00:00:00 2001 From: Qqwy/W-M at Quinn Date: Sat, 10 Jun 2017 18:12:35 +0200 Subject: [PATCH 1/7] server pid test. --- lib/exactor/operations.ex | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/exactor/operations.ex b/lib/exactor/operations.ex index efd9f3f..f9ab25e 100644 --- a/lib/exactor/operations.ex +++ b/lib/exactor/operations.ex @@ -636,13 +636,13 @@ defmodule ExActor.Operations do case options[:export] do local when is_atom(local) and local != nil and local != false -> local {:local, local} -> local - _ -> quote(do: server) + _ -> quote(do: server_pid(server)) end end defp server_ref(options, _) do case options[:export] do - default when default in [nil, false, true] -> quote(do: server) + default when default in [nil, false, true] -> quote(do: server_pid(server)) local when is_atom(local) -> local {:local, local} -> local {:global, _} = global -> global @@ -817,4 +817,18 @@ defmodule ExActor.Operations do end ) end + + @doc """ + By default, the `server` argument given + to the different interface functions, is expected to be a process identifier, + unless overridden by the `export:` option. + + But by providing a custom implementation of `server_pid/1`, you can map an identifier + to a PID by some other means. + """ + def server_pid(server_reference) do + server_reference + end + + defoverridable [server_pid: 1] end From c4718efe7b2f21045db1c4add3260591059056a7 Mon Sep 17 00:00:00 2001 From: Qqwy/W-M at Quinn Date: Sat, 10 Jun 2017 18:16:47 +0200 Subject: [PATCH 2/7] adding server_pid/1. --- lib/exactor/gen_server.ex | 14 ++++++++++++++ lib/exactor/operations.ex | 18 ++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/exactor/gen_server.ex b/lib/exactor/gen_server.ex index 7607c58..82f8d91 100644 --- a/lib/exactor/gen_server.ex +++ b/lib/exactor/gen_server.ex @@ -26,6 +26,20 @@ defmodule ExActor.GenServer do import ExActor.Responders unquote(ExActor.Helper.init_generation_state(opts)) + + @doc """ + By default, the `server` argument given + to the different interface functions, is expected to be a process identifier, + unless overridden by the `export:` option. + + But by providing a custom implementation of `server_pid/1`, you can map an identifier + to a PID by some other means. + """ + def server_pid(server_reference) do + server_reference + end + + defoverridable [server_pid: 1] end end end diff --git a/lib/exactor/operations.ex b/lib/exactor/operations.ex index f9ab25e..efd9f3f 100644 --- a/lib/exactor/operations.ex +++ b/lib/exactor/operations.ex @@ -636,13 +636,13 @@ defmodule ExActor.Operations do case options[:export] do local when is_atom(local) and local != nil and local != false -> local {:local, local} -> local - _ -> quote(do: server_pid(server)) + _ -> quote(do: server) end end defp server_ref(options, _) do case options[:export] do - default when default in [nil, false, true] -> quote(do: server_pid(server)) + default when default in [nil, false, true] -> quote(do: server) local when is_atom(local) -> local {:local, local} -> local {:global, _} = global -> global @@ -817,18 +817,4 @@ defmodule ExActor.Operations do end ) end - - @doc """ - By default, the `server` argument given - to the different interface functions, is expected to be a process identifier, - unless overridden by the `export:` option. - - But by providing a custom implementation of `server_pid/1`, you can map an identifier - to a PID by some other means. - """ - def server_pid(server_reference) do - server_reference - end - - defoverridable [server_pid: 1] end From 533475649ec37ddcd26e84f9525715f165ad74b5 Mon Sep 17 00:00:00 2001 From: Sasa Juric Date: Sat, 10 Jun 2017 19:35:16 +0200 Subject: [PATCH 3/7] refactor interface definition --- lib/exactor/operations.ex | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/lib/exactor/operations.ex b/lib/exactor/operations.ex index efd9f3f..a3676d4 100644 --- a/lib/exactor/operations.ex +++ b/lib/exactor/operations.ex @@ -582,31 +582,20 @@ defmodule ExActor.Operations do } end - arity = length(interface_args) - unless private do - if guard do - def unquote(req_name)(unquote_splicing(interface_args)) - when unquote(guard) - do - GenServer.unquote(server_fun)(unquote_splicing(gen_server_args)) - end - else - def unquote(req_name)(unquote_splicing(interface_args)) do - GenServer.unquote(server_fun)(unquote_splicing(gen_server_args)) - end - end - else - if guard do - defp unquote(req_name)(unquote_splicing(interface_args)) - when unquote(guard) - do - GenServer.unquote(server_fun)(unquote_splicing(gen_server_args)) - end - else - defp unquote(req_name)(unquote_splicing(interface_args)) do - GenServer.unquote(server_fun)(unquote_splicing(gen_server_args)) - end + interface_body = + quote do + GenServer.unquote(server_fun)(unquote_splicing(gen_server_args)) end + + cond do + private == nil && guard == nil -> + def unquote(req_name)(unquote_splicing(interface_args)), do: unquote(interface_body) + private == nil && guard != nil -> + def unquote(req_name)(unquote_splicing(interface_args)) when unquote(guard), do: unquote(interface_body) + private != nil && guard == nil -> + defp unquote(req_name)(unquote_splicing(interface_args)), do: unquote(interface_body) + private != nil && guard != nil -> + defp unquote(req_name)(unquote_splicing(interface_args)) when unquote(guard), do: unquote(interface_body) end end end From f1c8d0ea88937320b81ee107ed69a679689d1de6 Mon Sep 17 00:00:00 2001 From: Qqwy/W-M at Quinn Date: Sat, 10 Jun 2017 22:49:32 +0200 Subject: [PATCH 4/7] Adds ExActor.Common containing server_pid/1 function. --- lib/exactor/common.ex | 22 ++++++++++++++++++++++ lib/exactor/empty.ex | 17 +++++++++++++++++ lib/exactor/gen_server.ex | 15 +-------------- lib/exactor/operations.ex | 7 ++++++- lib/exactor/strict.ex | 1 + lib/exactor/tolerant.ex | 2 ++ 6 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 lib/exactor/common.ex diff --git a/lib/exactor/common.ex b/lib/exactor/common.ex new file mode 100644 index 0000000..fb0204d --- /dev/null +++ b/lib/exactor/common.ex @@ -0,0 +1,22 @@ +defmodule ExActor.Common do + @moduledoc false + + # This module adds common functionality to all ExActor behaviours. + defmacro __using__(_opts) do + quote do + @doc """ + By default, the `server` argument given + to the different interface functions, is expected to be a process identifier, + unless overridden by the `export:` option. + + But by providing a custom implementation of `server_pid/1`, you can map an identifier + to a PID by some other means. + """ + def server_pid(server_reference) do + server_reference + end + + defoverridable [server_pid: 1] + end + end +end diff --git a/lib/exactor/empty.ex b/lib/exactor/empty.ex index abe0c69..9f30f11 100644 --- a/lib/exactor/empty.ex +++ b/lib/exactor/empty.ex @@ -21,6 +21,7 @@ defmodule ExActor.Empty do defmacro __using__(opts) do quote do @behaviour :gen_server + use ExActor.Common @generated_funs MapSet.new @@ -28,6 +29,22 @@ defmodule ExActor.Empty do import ExActor.Responders unquote(ExActor.Helper.init_generation_state(opts)) + + + + @doc """ + By default, the `server` argument given + to the different interface functions, is expected to be a process identifier, + unless overridden by the `export:` option. + + But by providing a custom implementation of `server_pid/1`, you can map an identifier + to a PID by some other means. + """ + def server_pid(server_reference) do + server_reference + end + + defoverridable [server_pid: 1] end end end diff --git a/lib/exactor/gen_server.ex b/lib/exactor/gen_server.ex index 82f8d91..2a358cb 100644 --- a/lib/exactor/gen_server.ex +++ b/lib/exactor/gen_server.ex @@ -19,6 +19,7 @@ defmodule ExActor.GenServer do defmacro __using__(opts) do quote do use GenServer + use ExActor.Common @generated_funs MapSet.new @@ -26,20 +27,6 @@ defmodule ExActor.GenServer do import ExActor.Responders unquote(ExActor.Helper.init_generation_state(opts)) - - @doc """ - By default, the `server` argument given - to the different interface functions, is expected to be a process identifier, - unless overridden by the `export:` option. - - But by providing a custom implementation of `server_pid/1`, you can map an identifier - to a PID by some other means. - """ - def server_pid(server_reference) do - server_reference - end - - defoverridable [server_pid: 1] end end end diff --git a/lib/exactor/operations.ex b/lib/exactor/operations.ex index a3676d4..45d8f40 100644 --- a/lib/exactor/operations.ex +++ b/lib/exactor/operations.ex @@ -582,9 +582,14 @@ defmodule ExActor.Operations do } end + [server_ref | gen_server_args_tail] = gen_server_args + + server_pid = quote(do: server_pid(unquote(server_ref))) + interface_gen_server_args = [server_pid | gen_server_args_tail] + interface_body = quote do - GenServer.unquote(server_fun)(unquote_splicing(gen_server_args)) + GenServer.unquote(server_fun)(unquote_splicing(interface_gen_server_args)) end cond do diff --git a/lib/exactor/strict.ex b/lib/exactor/strict.ex index 5b201bc..d551c20 100644 --- a/lib/exactor/strict.ex +++ b/lib/exactor/strict.ex @@ -28,6 +28,7 @@ defmodule ExActor.Strict do defmacro __using__(opts) do quote do use ExActor.Behaviour.Strict + use ExActor.Common @generated_funs MapSet.new diff --git a/lib/exactor/tolerant.ex b/lib/exactor/tolerant.ex index d7fb6b5..ad08e94 100644 --- a/lib/exactor/tolerant.ex +++ b/lib/exactor/tolerant.ex @@ -23,6 +23,7 @@ defmodule ExActor.Tolerant do defmacro __using__(opts) do quote do use ExActor.Behaviour.Tolerant + use ExActor.Common @generated_funs MapSet.new @@ -30,6 +31,7 @@ defmodule ExActor.Tolerant do import ExActor.Responders unquote(ExActor.Helper.init_generation_state(opts)) + end end end From 50c4638ae9dd016c316b90d3547ac81c72f1ba68 Mon Sep 17 00:00:00 2001 From: Qqwy/W-M at Quinn Date: Sat, 10 Jun 2017 22:50:21 +0200 Subject: [PATCH 5/7] cleanup --- lib/exactor/empty.ex | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/lib/exactor/empty.ex b/lib/exactor/empty.ex index 9f30f11..bc6b312 100644 --- a/lib/exactor/empty.ex +++ b/lib/exactor/empty.ex @@ -29,22 +29,6 @@ defmodule ExActor.Empty do import ExActor.Responders unquote(ExActor.Helper.init_generation_state(opts)) - - - - @doc """ - By default, the `server` argument given - to the different interface functions, is expected to be a process identifier, - unless overridden by the `export:` option. - - But by providing a custom implementation of `server_pid/1`, you can map an identifier - to a PID by some other means. - """ - def server_pid(server_reference) do - server_reference - end - - defoverridable [server_pid: 1] end end end From 2185cc7c0bc3edb29209520ecc8ead7350159338 Mon Sep 17 00:00:00 2001 From: Qqwy/W-M at Quinn Date: Sat, 10 Jun 2017 23:00:43 +0200 Subject: [PATCH 6/7] WIP... --- lib/exactor/operations.ex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/exactor/operations.ex b/lib/exactor/operations.ex index 45d8f40..a4783f8 100644 --- a/lib/exactor/operations.ex +++ b/lib/exactor/operations.ex @@ -571,6 +571,7 @@ defmodule ExActor.Operations do interface_args: Macro.escape(interface_args(interface_matches, options), unquote: true), gen_server_args: Macro.escape(gen_server_args(options, type, payload), unquote: true), guard: Macro.escape(guard(options, :interface), unquote: true) + # export_option?: Keyword.get(options, :export, nil) ] do {interface_args, gen_server_args} = unless type in [:multicall, :abcast] do @@ -582,10 +583,12 @@ defmodule ExActor.Operations do } end + # Extract the server reference as first argument, + # And call `server_pid/1` on it inside the interface implementation. + # (But not in the function head) [server_ref | gen_server_args_tail] = gen_server_args - - server_pid = quote(do: server_pid(unquote(server_ref))) - interface_gen_server_args = [server_pid | gen_server_args_tail] + server_pid_quote = quote(do: server_pid(unquote(server_ref))) + interface_gen_server_args = [server_pid_quote | gen_server_args_tail] interface_body = quote do From e0f648916939cc358e541637a096c25799230611 Mon Sep 17 00:00:00 2001 From: Qqwy/W-M at Quinn Date: Sat, 10 Jun 2017 23:03:33 +0200 Subject: [PATCH 7/7] Build in conditional check for multicall, abcast. --- lib/exactor/operations.ex | 25 +++++++++++++++---------- lib/exactor/tolerant.ex | 1 - 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/exactor/operations.ex b/lib/exactor/operations.ex index a4783f8..2375191 100644 --- a/lib/exactor/operations.ex +++ b/lib/exactor/operations.ex @@ -570,8 +570,8 @@ defmodule ExActor.Operations do server_fun: server_fun(type), interface_args: Macro.escape(interface_args(interface_matches, options), unquote: true), gen_server_args: Macro.escape(gen_server_args(options, type, payload), unquote: true), - guard: Macro.escape(guard(options, :interface), unquote: true) - # export_option?: Keyword.get(options, :export, nil) + guard: Macro.escape(guard(options, :interface), unquote: true), + export_option: Macro.escape(options[:export], unquote: true) ] do {interface_args, gen_server_args} = unless type in [:multicall, :abcast] do @@ -583,17 +583,22 @@ defmodule ExActor.Operations do } end - # Extract the server reference as first argument, - # And call `server_pid/1` on it inside the interface implementation. - # (But not in the function head) - [server_ref | gen_server_args_tail] = gen_server_args - server_pid_quote = quote(do: server_pid(unquote(server_ref))) - interface_gen_server_args = [server_pid_quote | gen_server_args_tail] + interface_gen_server_args = + if type in [:multicall, :abcast] || export_option do + gen_server_args + else + # Extract the server reference as first argument, + # And call `server_pid/1` on it inside the interface implementation. + # (But not in the function head) + [server_ref | gen_server_args_tail] = gen_server_args + server_pid_quote = quote(do: server_pid(unquote(server_ref))) + [server_pid_quote | gen_server_args_tail] + end interface_body = quote do - GenServer.unquote(server_fun)(unquote_splicing(interface_gen_server_args)) - end + GenServer.unquote(server_fun)(unquote_splicing(interface_gen_server_args)) + end cond do private == nil && guard == nil -> diff --git a/lib/exactor/tolerant.ex b/lib/exactor/tolerant.ex index ad08e94..37eea9b 100644 --- a/lib/exactor/tolerant.ex +++ b/lib/exactor/tolerant.ex @@ -31,7 +31,6 @@ defmodule ExActor.Tolerant do import ExActor.Responders unquote(ExActor.Helper.init_generation_state(opts)) - end end end