Create OpenSearch index on startup with Snap

So, I have a set of child processes under my start/2 callback, as you do:

  @impl true
  def start(_type, _args) do
    children = [
      MyAppWeb.Telemetry,
      MyApp.Repo,
      {DNSCluster, query: Application.get_env(:caque, :dns_cluster_query) || :ignore},
      {Phoenix.PubSub, name: MyApp.PubSub},
      # Start the Finch HTTP client for sending emails
      {Finch, name: MyApp.Finch},
      {MyApp.Documents.Cluster, name: :document_cluster},
      # Start a worker by calling: MyApp.Worker.start_link(arg)
      # {MyApp.Worker, arg},
      # Start to serve requests, typically the last entry
      MyAppWeb.Endpoint
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, max_restarts: 5, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end

I’m using the Snap library to integrate OpenSearch. The Snap docs have it,

Each cluster defines start_link/1 which must be invoked before using the cluster and optionally accepts an explicit config. It creates the supervision tree, including the connection pool.

Include it in your application:

def start(_type, _args) do
  children = [
    {MyApp.Cluster, []}
  ]

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

Okay, okay, so I did all that. But… I’ve got a problem.

I want to set up my app to create a certain index on startup. That is, when my application starts, I want it to check if there’s an index named "docs" under the Documents cluster (defined by MyApp.Documents.Cluster). If no such index exists, the app should create one.

MyApp.Documents.Cluster already uses the Snap.Cluster module, which implements GenServer. So I can’t define start_link in Documents.Cluster in order to spin up an index on startup.

What would be the best/most idiomatic way to spin up an index on startup? In a separate module? As some kind of appendage to Documents.Cluster? What’s the best way?

I notice in the Snap docs that init/1 is listed under defoverridable. Does that mean it’s safe to override, and use that to start the index?

Snap.Cluster does not implement GenServer. If it did, you could use a continue.

Yep. Note that doing things in init blocks the supervisor from starting subsequent children until it returns.

2 Likes