NimblePool implementation WIP
This commit is contained in:
parent
0bc39d9ad1
commit
a84d227040
5 changed files with 79 additions and 2 deletions
13
README.md
13
README.md
|
@ -78,7 +78,7 @@ iex(1)> GenMagic.Helpers.perform_once(Path.join(File.cwd!(), "Makefile"))
|
||||||
|
|
||||||
### Supervised Requests
|
### Supervised Requests
|
||||||
|
|
||||||
The Server should be run under a pool which provides concurrency *and* resiliency.
|
The Server should be run under a supervisor which provides resiliency.
|
||||||
|
|
||||||
Here we run it under a supervisor:
|
Here we run it under a supervisor:
|
||||||
|
|
||||||
|
@ -96,6 +96,17 @@ iex(2)> GenMagic.Server.perform(:gen_magic, Path.expand("~/.bash_history"))
|
||||||
|
|
||||||
Note that in this case we have opted to use a named process.
|
Note that in this case we have opted to use a named process.
|
||||||
|
|
||||||
|
### Pool
|
||||||
|
|
||||||
|
For concurrency *and* resiliency, you may start the `GenMagic.Pool`. By default, it will start a `GenMagic.Server`
|
||||||
|
worker per online scheduler:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex(1)> GenMagic.Pool.start_link([])
|
||||||
|
iex(2)> GenMagic.Pool.perform(GenMagic.Pool, Path.expand("~/.bash_history"))
|
||||||
|
{:ok, [mime_type: "text/plain", encoding: "us-ascii", content: "ASCII text"]}
|
||||||
|
```
|
||||||
|
|
||||||
### Check Uploaded Files
|
### Check Uploaded Files
|
||||||
|
|
||||||
If you use Phoenix, you can inspect the file from your controller:
|
If you use Phoenix, you can inspect the file from your controller:
|
||||||
|
|
55
lib/gen_magic/pool.ex
Normal file
55
lib/gen_magic/pool.ex
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
defmodule GenMagic.Pool do
|
||||||
|
@behaviour NimblePool
|
||||||
|
|
||||||
|
def start_link(options, pool_size \\ nil) do
|
||||||
|
pool_size = pool_size || System.schedulers_online()
|
||||||
|
NimblePool.start_link(worker: {__MODULE__, options}, pool_size: pool_size)
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform(pool, path, opts \\ []) do
|
||||||
|
pool_timeout = Keyword.get(opts, :pool_timeout, 5000)
|
||||||
|
timeout = Keyword.get(opts, :timeout, 5000)
|
||||||
|
|
||||||
|
NimblePool.checkout!(pool, :checkout, fn _from, server ->
|
||||||
|
{GenMagic.perform(server, path, timeout), server}
|
||||||
|
end, pool_timeout)
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl NimblePool
|
||||||
|
def init_pool(options) do
|
||||||
|
{name, options} = case Keyword.pop(options, :name) do
|
||||||
|
{name, options} when is_atom(name) -> {name, options}
|
||||||
|
{nil, options} -> {__MODULE__, options}
|
||||||
|
{_, options} -> {nil, options}
|
||||||
|
end
|
||||||
|
if name, do: Process.register(self(), atom)
|
||||||
|
{:ok, options}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl NimblePool
|
||||||
|
def init_worker(options) do
|
||||||
|
{:ok, server} = GenMagic.Server.start_link(options)
|
||||||
|
{:ok, server, nil}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl NimblePool
|
||||||
|
def handle_checkout(:checkout, _, server, state) do
|
||||||
|
{:ok, server, server, pool_state}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl NimblePool
|
||||||
|
def handle_checkin(server, _from, _old_server, state) do
|
||||||
|
{:ok, server, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl NimblePool
|
||||||
|
def terminate_worker(_reason, _worker, state) do
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl NimblePool
|
||||||
|
def terminate(_reason, _conn, state) do
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
3
mix.exs
3
mix.exs
|
@ -44,7 +44,8 @@ defmodule GenMagic.MixProject do
|
||||||
{:credo, "~> 1.4.0", only: [:dev, :test], runtime: false},
|
{:credo, "~> 1.4.0", only: [:dev, :test], runtime: false},
|
||||||
{:dialyxir, "~> 1.0.0-rc.6", only: :dev, runtime: false},
|
{:dialyxir, "~> 1.0.0-rc.6", only: :dev, runtime: false},
|
||||||
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
|
{:ex_doc, ">= 0.0.0", only: :dev, runtime: false},
|
||||||
{:elixir_make, "~> 0.4", runtime: false}
|
{:elixir_make, "~> 0.4", runtime: false},
|
||||||
|
{:nimble_pool, "~> 0.1"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
1
mix.lock
1
mix.lock
|
@ -12,4 +12,5 @@
|
||||||
"makeup": {:hex, :makeup, "1.0.1", "82f332e461dc6c79dbd82fbe2a9c10d48ed07146f0a478286e590c83c52010b5", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49736fe5b66a08d8575bf5321d716bac5da20c8e6b97714fec2bcd6febcfa1f8"},
|
"makeup": {:hex, :makeup, "1.0.1", "82f332e461dc6c79dbd82fbe2a9c10d48ed07146f0a478286e590c83c52010b5", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49736fe5b66a08d8575bf5321d716bac5da20c8e6b97714fec2bcd6febcfa1f8"},
|
||||||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
|
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
|
||||||
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
|
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
|
||||||
|
"nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"},
|
||||||
}
|
}
|
||||||
|
|
9
test/gen_magic/pool_test.exs
Normal file
9
test/gen_magic/pool_test.exs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
defmodule GenMagic.PoollTest do
|
||||||
|
use GenMagic.MagicCase
|
||||||
|
|
||||||
|
test "pool" do
|
||||||
|
{:ok, _} = GenMagic.Pool.start_link([name: TestPool])
|
||||||
|
assert {:ok, _} = GenMagic.Pool.perform(TestPool, absolute_path("Makefile"))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue