Failed to start poolboy pool

I have a Genserver which handles connections to Elasticsearch. It works fine and I can start it from iex using ElasticSearch.start_link. Now, since elasticsearch can’t handle too many connections, I am introducing a pool. I am using poolboy library to do that. Here is my pool looks like

defmodule ElasticSearch.Pool do
  @moduledoc """
  Providing a connection pooling for elasticsearch
  """
  use Supervisor

  def start_link do
    Supervisor.start_link(__MODULE__, [])
  end

  def init([]) do
    pool_opts = [
      name: {:local, :espool},
      worker_module: ElasticSearch,
      size: 10,
      max_overflow: 100,
      timeout: :inifinity
    ]

    children = [
      :poolboy.child_spec(:espool, pool_opts, [])
    ]

    supervise(children, strategy: :one_for_one, name: __MODULE__)
  end

  def create_index(name, settings) do
    :poolboy.transaction(:espool, &ElasticSearch.create_index(&1, name, settings))
  end
end

In my supervision tree, I have the following:

defmodule Dedup do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      supervisor(RedixPool, []),
      supervisor(ElasticSearch.Pool, []),
    ]

    opts = [strategy: :one_for_one, name: Dedup.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

When I try to start my app, the following error occurs.

17:22:35.239 [info]  Application dedup exited: Dedup.start(:normal, []) returned an error: shutdown: failed to start child: ElasticSearch.Pool
    ** (EXIT) shutdown: failed to start child: :espool
        ** (EXIT) an exception was raised:
            ** (MatchError) no match of right hand side value: {:error, {:EXIT, {:undef, [{ElasticSearch, :start_link, [[]], []}, {:supervisor, :do_start_child_i, 3, [file: 'supervisor.erl', line: 374]}, {:supervisor, :handle_call, 3, [file: 'supervisor.erl', line: 399]}, {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 629]}, {:gen_server, :handle_msg, 5, [file: 'gen_server.erl', line: 661]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 240]}]}}}
                (poolboy) src/poolboy.erl:275: :poolboy.new_worker/1
                (poolboy) src/poolboy.erl:296: :poolboy.prepopulate/3
                (poolboy) src/poolboy.erl:145: :poolboy.init/3
                (stdlib) gen_server.erl:328: :gen_server.init_it/6
                (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3

I am not sure what am I doing wrong. Starting the genserver directly ((ElasticSearch.start_link) seems to work. When I change

    children = [
          :poolboy.child_spec(:espool, pool_opts, [])
       ]

to

children = [
      worker(ElasticSearch, [])
    ]

it works. But pooling is gone. So my guess is the error has to do something with the way poolboy works.

Any help would be great.

poolboy requires workers to have start_link/1 and the worker args are passed as the single argument, rather than a list of arguments.

3 Likes

Thanks. That was the problem. Working fine now.

Perhaps for future readers (and myself) you could post the code that worked?

1 Like