Packages
phoenix_kit
1.6.6
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/phoenix_kit/install/oban_config.ex
defmodule PhoenixKit.Install.ObanConfig do
@moduledoc """
Handles Oban configuration for PhoenixKit installation.
This module provides functionality to:
- Configure Oban for background job processing
- Set up required queues (default, emails, file_processing)
- Add Oban.Plugins.Pruner for job cleanup
- Add Oban to application supervisor tree
- Ensure configuration exists during updates
"""
use PhoenixKit.Install.IgniterCompat
alias PhoenixKit.Install.IgniterHelpers
@doc """
Adds or verifies Oban configuration.
This function ensures that Oban is properly configured for PhoenixKit's
background job processing, including:
1. Repo configuration (auto-detected from PhoenixKit config)
2. Required queues for file processing and email handling
3. Pruner plugin for automatic job cleanup
## Parameters
- `igniter` - The igniter context
## Returns
Updated igniter with Oban configuration and notices.
"""
def add_oban_configuration(igniter) do
igniter
|> add_oban_config()
|> add_oban_configuration_notice()
end
@doc """
Checks if Oban configuration exists in config.exs.
## Parameters
- `igniter` - The igniter context for detecting parent app name
## Returns
Boolean indicating if configuration exists.
"""
def oban_config_exists?(igniter) do
config_path = "config/config.exs"
app_name = IgniterHelpers.get_parent_app_name(igniter)
if File.exists?(config_path) do
content = File.read!(config_path)
lines = String.split(content, "\n")
# Check for active (non-commented) Oban configuration with parent app namespace
has_oban_config =
Enum.any?(lines, fn line ->
trimmed = String.trim(line)
# Not a comment and contains config :app_name, Oban
!String.starts_with?(trimmed, "#") and
String.contains?(line, "config :#{app_name}, Oban")
end)
has_queues =
Enum.any?(lines, fn line ->
trimmed = String.trim(line)
# Not a comment and contains queues:
!String.starts_with?(trimmed, "#") and String.contains?(line, "queues:")
end)
has_oban_config and has_queues
else
false
end
rescue
_ -> false
end
# Add Oban configuration to config.exs
defp add_oban_config(igniter) do
# Get parent app name and repo
app_name = IgniterHelpers.get_parent_app_name(igniter)
repo_module = get_repo_module(igniter)
oban_config = """
# Configure Oban for PhoenixKit background jobs
# Required for file processing (storage system) and email handling
config :#{app_name}, Oban,
repo: #{repo_module},
queues: [
default: 10, # General purpose queue
emails: 50, # Email processing
file_processing: 20 # File variant generation (storage system)
],
plugins: [
Oban.Plugins.Pruner # Automatic cleanup of completed jobs
]
"""
try do
Igniter.update_file(igniter, "config/config.exs", fn source ->
content = Rewrite.Source.get(source, :content)
# Check if Oban config already exists
if String.contains?(content, "config :#{app_name}, Oban") do
source
else
# Find insertion point before import_config statements
insertion_point = find_import_config_location(content)
updated_content =
case insertion_point do
{:before_import, before_content, after_content} ->
# Insert before import_config
before_content <> oban_config <> "\n" <> after_content
:append_to_end ->
# No import_config found, append to end
content <> oban_config
end
Rewrite.Source.update(source, :content, updated_content)
end
end)
rescue
e ->
IO.warn("Failed to add Oban configuration: #{inspect(e)}")
add_manual_config_notice(igniter, repo_module)
end
end
# Get repo module from PhoenixKit config or use placeholder
defp get_repo_module(_igniter) do
config_path = "config/config.exs"
if File.exists?(config_path) do
content = File.read!(config_path)
# Look for existing PhoenixKit repo config
case Regex.run(~r/config :phoenix_kit,\s+repo:\s+([A-Za-z0-9_.]+)/, content) do
[_, repo] -> repo
_ -> "MyApp.Repo"
end
else
"MyApp.Repo"
end
rescue
_ -> "MyApp.Repo"
end
# Find the location to insert config before import_config statements
defp find_import_config_location(content) do
lines = String.split(content, "\n")
# Look for import_config pattern
import_index =
Enum.find_index(lines, fn line ->
trimmed = String.trim(line)
String.starts_with?(trimmed, "import_config") or String.contains?(line, "import_config")
end)
case import_index do
nil ->
# No import_config found, append to end
:append_to_end
index ->
# Find the start of the import_config block
start_index = find_import_block_start(lines, index)
# Split content at the start of import block
before_lines = Enum.take(lines, start_index)
after_lines = Enum.drop(lines, start_index)
before_content = Enum.join(before_lines, "\n")
after_content = Enum.join(after_lines, "\n")
{:before_import, before_content, after_content}
end
end
# Find the start of the import_config block (including preceding comments)
defp find_import_block_start(lines, import_index) do
lines
|> Enum.take(import_index)
|> Enum.reverse()
|> Enum.reduce_while(import_index, fn line, current_index ->
trimmed = String.trim(line)
cond do
# Comment line related to import
String.starts_with?(trimmed, "#") and
(String.contains?(line, "import") or String.contains?(line, "Import") or
String.contains?(line, "bottom") or String.contains?(line, "BOTTOM") or
String.contains?(line, "environment")) ->
{:cont, current_index - 1}
# Blank line
trimmed == "" ->
{:cont, current_index - 1}
# config_env or similar
String.contains?(line, "config_env()") or String.contains?(line, "env_config") ->
{:cont, current_index - 1}
# Stop at any other code
true ->
{:halt, current_index}
end
end)
end
# Add notice about Oban configuration
defp add_oban_configuration_notice(igniter) do
if oban_config_exists?(igniter) do
Igniter.add_notice(
igniter,
"⚙️ Oban configured for background jobs (file processing, emails)"
)
else
Igniter.add_notice(
igniter,
"⚠️ Oban configuration added - restart your server if running"
)
end
end
@doc """
Adds Oban to the parent application's supervision tree.
This function ensures that Oban starts automatically when the application starts,
positioned after PhoenixKit.Supervisor to ensure PhoenixKit services are available
before Oban workers run.
## Parameters
- `igniter` - The igniter context
## Returns
Updated igniter with Oban added to application supervisor.
"""
def add_oban_supervisor(igniter) do
app_name = IgniterHelpers.get_parent_app_name(igniter)
app_file = "lib/#{app_name}/application.ex"
oban_line = " {Oban, Application.get_env(:#{app_name}, Oban)},"
Igniter.update_file(igniter, app_file, fn source ->
update_application_with_oban(source, app_name, oban_line)
end)
end
# Update application.ex source with Oban supervisor
defp update_application_with_oban(source, app_name, oban_line) do
content = Rewrite.Source.get(source, :content)
if oban_already_configured?(content, app_name) do
source
else
updated_content = insert_or_replace_oban(content, oban_line)
Rewrite.Source.update(source, :content, updated_content)
end
end
# Check if Oban is already properly configured
defp oban_already_configured?(content, app_name) do
String.contains?(content, "{Oban, Application.get_env(:#{app_name}, Oban)}")
end
# Insert or replace Oban configuration in application.ex
defp insert_or_replace_oban(content, oban_line) do
lines = String.split(content, "\n")
has_bare_oban = Enum.any?(lines, fn line -> String.trim(line) == "Oban," end)
updated_lines = process_application_lines(lines, oban_line, has_bare_oban)
Enum.join(updated_lines, "\n")
end
# Process each line to insert/replace Oban
defp process_application_lines(lines, oban_line, has_bare_oban) do
Enum.reduce(lines, [], fn line, acc ->
trimmed = String.trim(line)
cond do
# Replace bare "Oban," with proper config
trimmed == "Oban," ->
acc ++ [oban_line]
# Insert Oban after PhoenixKit.Supervisor ONLY if there's no bare Oban to replace
String.contains?(line, "PhoenixKit.Supervisor") and not has_bare_oban ->
acc ++ [line, oban_line]
true ->
acc ++ [line]
end
end)
end
@doc """
Checks if Oban supervisor is configured in application.ex.
## Parameters
- `igniter` - The igniter context for detecting parent app name
## Returns
Boolean indicating if Oban supervisor exists in application.ex.
"""
def oban_supervisor_exists?(igniter) do
app_name = IgniterHelpers.get_parent_app_name(igniter)
app_file = "lib/#{app_name}/application.ex"
if File.exists?(app_file) do
content = File.read!(app_file)
# Check for Oban in children list
String.contains?(content, "{Oban,") or
String.contains?(content, "Application.get_env(:#{app_name}, Oban)")
else
false
end
rescue
_ -> false
end
# Add notice when manual configuration is required
defp add_manual_config_notice(igniter, repo_module) do
app_name = IgniterHelpers.get_parent_app_name(igniter)
notice = """
⚠️ Manual Configuration Required: Oban
PhoenixKit couldn't automatically configure Oban for background jobs.
Please add the following to config/config.exs:
config :#{app_name}, Oban,
repo: #{repo_module},
queues: [
default: 10,
emails: 50,
file_processing: 20
],
plugins: [
Oban.Plugins.Pruner
]
And add the following to lib/#{app_name}/application.ex in the children list:
{Oban, Application.get_env(:#{app_name}, Oban)}
Without this configuration, the storage system cannot process uploaded files.
Files will remain stuck in "processing" status.
"""
Igniter.add_notice(igniter, notice)
end
end