defmodule Component.Strategy.Pooled.Scheduler do

  @moduledoc """

  This is the runtime support for pooled workers.

  Each original module that specifies a pool arg will be associated with
  its own pool, and that pool is run by the scheduler code below.

  """


    defdelegate start_new_pool(args),
      to: Component.Strategy.Pooled.Supervisor,
      as: :start_link


    @doc """
    Run an instance of our pool worker with the given command. The
    optional third parameter is a timeout. If a float, the value is in
    seconds; otherwise it's an integer number of milliseconds.

    This is called by the delegating function in the code generated by
    Component.Strategy.Pooled—it isn't called directly by the client.
    """

    def run(pool, what_to_run, timeout) when is_float(timeout) do
      run(pool, what_to_run, round(timeout * 1000 + 0.4999))
    end

    def run(pool, what_to_run, timeout) do
      :poolboy.transaction(pool, &GenServer.call(&1, what_to_run, timeout), timeout)
    end

    @doc """
    Claim a worker from the pool.
    """

    defdelegate checkout(pool), to: :poolboy
    defdelegate checkin(pool, worker),  to: :poolboy

  end
