Current section
Files
Jump to
Current section
Files
lib/pool.ex
defmodule OpenCC.Pool do
@moduledoc """
A NimblePool for concurrent OpenCC conversions.
"""
@behaviour NimblePool
# --- Client API ---
def child_spec(opts) do
%{
id: Keyword.get(opts, :name, __MODULE__),
start: {__MODULE__, :start_link, [opts]}
}
end
def start_link(opts) do
name = Keyword.fetch!(opts, :name)
pool_size = Keyword.get(opts, :pool_size, System.schedulers_online())
# pass opts down as worker config
NimblePool.start_link(
worker: {__MODULE__, opts},
pool_size: pool_size,
name: name
)
end
def convert(pool_name, text) when is_binary(text) do
# checkout a Rust ref from the pool
# doing the work in the CALLER's process
NimblePool.checkout!(pool_name, :checkout, fn _pool_pid, ref ->
result = OpenCC.Native.convert(ref, text)
{result, ref}
end)
end
# --- NimblePool callbacks ---
@impl NimblePool
def init_worker(pool_state) do
opts = pool_state
# initialize the Rust NIF instance
result = cond do
Keyword.has_key?(opts, :built_in) ->
OpenCC.Native.new_builtin(Atom.to_string(opts[:built_in]))
Keyword.has_key?(opts, :custom) ->
OpenCC.Native.new_custom(opts[:custom])
end
case result do
{:ok, ref} -> {:ok, ref, pool_state}
{:error, reason} -> {:error, reason}
end
end
@impl NimblePool
def handle_checkout(:checkout, _from, ref, pool_state) do
# give the ref to the caller
{:ok, ref, ref, pool_state}
end
@impl NimblePool
def handle_checkin(_result, _from, ref, pool_state) do
# take the ref back into the pool
{:ok, ref, pool_state}
end
@impl NimblePool
def terminate_worker(_reason, _ref, _pool_state) do
# rust NIF memory drops automatically on GC
:ok
end
end