From 60fde9c3ce51640e4907b3fb71a4dd3f2e9c46c5 Mon Sep 17 00:00:00 2001 From: Jordan Bracco Date: Mon, 15 Jun 2020 13:57:39 +0200 Subject: [PATCH] Unified API: `GenMagic.perform/2,3` --- README.md | 18 +++++++++--------- lib/gen_magic.ex | 33 +++++++++++++++++++++++++++++++++ lib/gen_magic/server.ex | 6 ++++-- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a182566..7d1d402 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Depending on the use case, you may utilise a single (one-off) GenMagic process w To use GenMagic directly, you can use `GenMagic.Helpers.perform_once/1`: ```elixir -iex(1)> GenMagic.Helpers.perform_once "." +iex(1)> GenMagic.perform(".", once: true) {:ok, %GenMagic.Result{ content: "directory", @@ -40,7 +40,7 @@ To use the GenMagic server as a daemon, you can start it first, keep a reference ```elixir {:ok, pid} = GenMagic.Server.start_link([]) -{:ok, result} = GenMagic.Server.perform(pid, path) +{:ok, result} = GenMagic.perform(path, server: pid) ``` See `GenMagic.Server.start_link/1` and `t:GenMagic.Server.option/0` for more information on startup parameters. @@ -67,7 +67,7 @@ See `t:GenMagic.Server.option/0` for details. For ad-hoc requests, you can use the helper method `GenMagic.Helpers.perform_once/2`: ```elixir -iex(1)> GenMagic.Helpers.perform_once(Path.join(File.cwd!(), "Makefile")) +iex(1)> GenMagic.perform(Path.join(File.cwd!(), "Makefile"), once: true) {:ok, %GenMagic.Result{ content: "makefile script, ASCII text", @@ -90,8 +90,8 @@ iex(1)> {:ok, pid} = Supervisor.start_link([{GenMagic.Server, name: :gen_magic}] Now we can ask it to inspect a file: ```elixir -iex(2)> GenMagic.Server.perform(:gen_magic, Path.expand("~/.bash_history")) -{:ok, [mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"]} +iex(2)> GenMagic.perform(Path.expand("~/.bash_history"), server: :gen_magic) +{:ok, %GenMagic.Result{mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"}} ``` Note that in this case we have opted to use a named process. @@ -114,11 +114,11 @@ You can add a pool in your application supervisor by adding it as a child: Supervisor.start_link(children, opts) ``` -And then you can use it with `GenMagic.Pool.perform/2`: +And then you can use it with `GenMagic.perform/2` with `pool: YourApp.GenMagicPool` option: ``` -iex(1)> GenMagic.Pool.perform(YourApp.GenMagicPool, Path.expand("~/.bash_history")) -{:ok, [mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"]} +iex(1)> GenMagic.perform(Path.expand("~/.bash_history"), pool: YourApp.GenMagicPool) +{:ok, %GenMagic.Result{mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"}} ``` ### Check Uploaded Files @@ -127,7 +127,7 @@ If you use Phoenix, you can inspect the file from your controller: ```elixir def upload(conn, %{"upload" => %{path: path}}) do, - {:ok, result} = GenMagic.Helpers.perform_once(:gen_magic, path) + {:ok, result} = GenMagic.perform(path, server: :gen_magic) text(conn, "Received your file containing #{result.content}") end ``` diff --git a/lib/gen_magic.ex b/lib/gen_magic.ex index f598521..292dfe8 100644 --- a/lib/gen_magic.ex +++ b/lib/gen_magic.ex @@ -4,4 +4,37 @@ defmodule GenMagic do See `GenMagic.Server` or the README for usage. """ + + @doc """ + Perform on `path`. + + An option of `server: ServerName`, `pool: PoolName` or `once: true` must be passed. + """ + @type option :: name + when name: {:pool, atom()} | {:server, GenMagic.Server.t()} | {:once, true} + + @spec perform(GenMagic.Server.target(), [option()]) :: GenMagic.Server.result() + def perform(path, opts, timeout \\ 5000) do + mod = cond do + Keyword.has_key?(opts, :pool) -> {GenMagic.Pool, Keyword.get(opts, :pool)} + Keyword.has_key?(opts, :server) -> {GenMagic.Server, Keyword.get(opts, :server)} + Keyword.has_key?(opts, :once) -> {GenMagic.Helpers, nil} + true -> nil + end + + if mod do + do_perform(mod, path, timeout) + else + {:error, :no_method} + end + end + + defp do_perform({GenMagic.Helpers, _}, path, timeout) do + GenMagic.Helpers.perform_once(path, timeout) + end + + defp do_perform({mod, name}, path, timeout) do + mod.perform(name, path, tiemout) + end + end diff --git a/lib/gen_magic/server.ex b/lib/gen_magic/server.ex index fc686b2..0e34586 100644 --- a/lib/gen_magic/server.ex +++ b/lib/gen_magic/server.ex @@ -55,6 +55,9 @@ defmodule GenMagic.Server do | {:recycle_threshold, non_neg_integer() | :infinity} | {:database_patterns, nonempty_list(:default | Path.t())} + @type target :: Path.t() | {:bytes, binary()} + @type result :: {:ok, Result.t()} | {:error, term() | String.t()} + @typedoc """ Current state of the Server: @@ -81,8 +84,7 @@ defmodule GenMagic.Server do @spec child_spec([option()]) :: Supervisor.child_spec() @spec start_link([option()]) :: :gen_statem.start_ret() - @spec perform(t(), Path.t() | {:bytes, binary()}, timeout()) :: - {:ok, Result.t()} | {:error, term() | String.t()} + @spec perform(t(), target(), timeout()) :: result() @spec status(t(), timeout()) :: {:ok, Status.t()} | {:error, term()} @spec stop(t(), term(), timeout()) :: :ok