Configuration
Primary runtime configuration lives in config/kaal.rb.
Core engine example
require "kaal"
Kaal.configure do |config|
config.backend = Kaal::Backend::MemoryAdapter.new
config.tick_interval = 5
config.window_lookback = 120
config.window_lookahead = 0
config.lease_ttl = 125
config.namespace = "kaal"
config.scheduler_config_path = "config/scheduler.yml"
config.enable_dispatch_recovery = true
config.enable_log_dispatch_registry = false
end
For the documented at-most-once dispatch guarantee, enable the dispatch log registry and keep lease_ttl >= window_lookback + tick_interval. See At-Most-Once Dispatch Guarantee.
Sequel adapter example
require "kaal"
require "kaal/sequel"
require "sequel"
database = Sequel.connect(adapter: "sqlite", database: File.expand_path("../db/kaal.sqlite3", __dir__))
Kaal.configure do |config|
config.backend = Kaal::Backend::DatabaseAdapter.new(database)
config.scheduler_config_path = "config/scheduler.yml"
end
Alternative SQL backends:
config.backend = Kaal::Backend::PostgresAdapter.new(database)
config.backend = Kaal::Backend::MySQLAdapter.new(database)
Active Record adapter example
require "kaal"
require "kaal/active_record"
Kaal::ActiveRecord::ConnectionSupport.configure!(
adapter: "sqlite3",
database: File.expand_path("../db/kaal.sqlite3", __dir__)
)
Kaal.configure do |config|
config.backend = Kaal::ActiveRecord::DatabaseAdapter.new
config.scheduler_config_path = "config/scheduler.yml"
end
Alternative SQL backends:
config.backend = Kaal::ActiveRecord::PostgresAdapter.new
config.backend = Kaal::ActiveRecord::MySQLAdapter.new
Rails plugin behavior
When you use kaal-rails, the plugin selects a backend from the Rails database adapter unless you override it yourself:
- SQLite ->
Kaal::ActiveRecord::DatabaseAdapter - PostgreSQL ->
Kaal::ActiveRecord::PostgresAdapter - MySQL ->
Kaal::ActiveRecord::MySQLAdapter
Install flow examples:
bundle exec rails generate kaal:install --backend=sqlite
bundle exec rails db:migrate
bundle exec rails generate kaal:install --backend=postgres
bundle exec rails db:migrate
bundle exec rails generate kaal:install --backend=mysql
bundle exec rails db:migrate
Explicit overrides still win:
Kaal.configure do |config|
config.backend = Kaal::Backend::MemoryAdapter.new
end
Sinatra addon behavior
When you use kaal-sinatra, the addon chooses the backend in this order:
- preserve
Kaal.configuration.backendif one is already set - use
backend:when you pass an explicit backend object - use
redis:when you pass a redis client - use
database:and infer SQLite / PostgreSQL / MySQL from the Sequel adapter - fall back to
Kaal::Backend::MemoryAdapterwhen nothing else is provided
For SQL-backed Sinatra apps, the addon selects a backend from the Sequel adapter unless you pass adapter: explicitly:
- SQLite ->
Kaal::Backend::DatabaseAdapter - PostgreSQL ->
Kaal::Backend::PostgresAdapter - MySQL ->
Kaal::Backend::MySQLAdapter
Typical setup:
require "kaal/sinatra"
Kaal::Sinatra.register!(
settings,
backend: Kaal::Backend::MemoryAdapter.new,
scheduler_config_path: "config/scheduler.yml",
namespace: "my-app",
start_scheduler: false
)
Redis setup:
require "redis"
redis = Redis.new(url: ENV.fetch("REDIS_URL"))
Kaal::Sinatra.register!(
settings,
redis: redis,
scheduler_config_path: "config/scheduler.yml"
)
Explicit backend overrides still win:
Kaal.configure do |config|
config.backend = Kaal::Backend::MemoryAdapter.new
end
Roda addon behavior
When you use kaal-roda, the addon chooses the backend in this order:
- preserve
Kaal.configuration.backendif one is already set - use
backend:when you pass an explicit backend object - use
redis:when you pass a redis client - use
database:and infer SQLite / PostgreSQL / MySQL from the Sequel adapter - fall back to
Kaal::Backend::MemoryAdapterwhen nothing else is provided
For SQL-backed Roda apps, the addon selects a backend from the Sequel adapter unless you pass adapter: explicitly:
- SQLite ->
Kaal::Backend::DatabaseAdapter - PostgreSQL ->
Kaal::Backend::PostgresAdapter - MySQL ->
Kaal::Backend::MySQLAdapter
Typical setup:
require "kaal/roda"
class App < Roda
plugin :kaal
kaal backend: Kaal::Backend::MemoryAdapter.new,
scheduler_config_path: "config/scheduler.yml",
namespace: "my-app",
start_scheduler: false
end
Redis setup:
require "redis"
redis = Redis.new(url: ENV.fetch("REDIS_URL"))
class App < Roda
plugin :kaal
kaal redis: redis,
scheduler_config_path: "config/scheduler.yml"
end
Explicit backend overrides still win:
Kaal.configure do |config|
config.backend = Kaal::Backend::MemoryAdapter.new
end
Hanami addon behavior
When you use kaal-hanami, the addon chooses the backend in this order:
- preserve
Kaal.configuration.backendif one is already set - use
backend:when you pass an explicit backend object - use
redis:when you pass a redis client - use
database:and infer SQLite / PostgreSQL / MySQL from the Sequel adapter - fall back to
Kaal::Backend::MemoryAdapterwhen nothing else is provided
For SQL-backed Hanami apps, the addon selects a backend from the Sequel adapter unless you pass adapter: explicitly:
- SQLite ->
Kaal::Backend::DatabaseAdapter - PostgreSQL ->
Kaal::Backend::PostgresAdapter - MySQL ->
Kaal::Backend::MySQLAdapter
Typical setup:
require "kaal/hanami"
module MyApp
class App < Hanami::App
Kaal::Hanami.configure!(
self,
backend: Kaal::Backend::MemoryAdapter.new,
scheduler_config_path: "config/scheduler.yml",
namespace: "my-app",
start_scheduler: false
)
end
end
Redis setup:
require "redis"
redis = Redis.new(url: ENV.fetch("REDIS_URL"))
module MyApp
class App < Hanami::App
Kaal::Hanami.configure!(self, redis: redis, scheduler_config_path: "config/scheduler.yml")
end
end
Explicit backend overrides still win:
Kaal.configure do |config|
config.backend = Kaal::Backend::MemoryAdapter.new
end
Key Options
| Setting | Default | Meaning |
|---|---|---|
backend | nil | Coordination or datastore backend |
tick_interval | 5 | Seconds between scheduler ticks |
window_lookback | 120 | Recovery window for missed runs |
window_lookahead | 0 | Optional future lookahead |
lease_ttl | 125 | Lock TTL for TTL-based adapters |
namespace | "kaal" | Prefix for coordination keys |
time_zone | nil | Scheduler interpretation zone; defaults to UTC |
scheduler_config_path | "config/scheduler.yml" | Scheduler file path |
enable_dispatch_recovery | true | Replay missed runs on startup |
enable_log_dispatch_registry | false | Persist dispatch records used by the documented at-most-once guarantee |
Time Zone Rules
- If
time_zoneis set, that zone is used to interpret cron expressions. - If
time_zoneis unset, Kaal usesUTC.