View Source Release Configuration
While having the same Oban configuration for every environment might be fine, there are certainly times you might want to make changes for a specific environment. For example, you may want to increase or decrease a queue's concurrency.
Using Config Providers
If you are using Elixir Releases, this is straight forward to do using Config Providers:
defmodule MyApp.ConfigProvider do
@moduledoc """
Provide release configuration for Oban Queue Concurrency
"""
@behaviour Config.Provider
def init(path) when is_binary(path), do: path
def load(config, path) do
case parse_json(path) do
nil ->
config
queues ->
Config.Reader.merge(config, ingestion: [{Oban, [queues: queues]}])
end
end
defp parse_json(path) do
{:ok, _} = Application.ensure_all_started(:jason)
if File.exists?(path) do
path
|> File.read!()
|> Jason.decode!()
|> Map.fetch!("queues")
|> Keyword.new(fn {key, value} -> {String.to_atom(key), value} end)
end
end
end
Our config provider ensures that the Jason
app is loaded so that we can parse
a JSON
configuration file. Once the JSON is loaded we must extract the
queues
map and convert it to a keyword list where all of the keys are atoms.
The use of String.to_atom/1
is safe because all of our queue names are
already defined.
Then you include this in your mix.exs
file, where your release is configured:
releases: [
umbrella_app: [
version: "0.0.1",
applications: [
child_app: :permanent
],
config_providers: [{Path.To.ConfigProvider, "/etc/config.json"}]
]
]
Then when you release your app, you ensure that you have a JSON file mounted at whatever path you specified above and that it contains all of your desired queues:
{"queues": {"special": 1, "default": 10, "events": 20}}