Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cron? trigger flag to control cron scheduler creation #5

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
spark_locals_without_parens = [
action: 1,
api: 1,
cron?: 1,
max_attempts: 1,
max_scheduler_attempts: 1,
on_error: 1,
Expand Down
17 changes: 15 additions & 2 deletions lib/ash_oban.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ defmodule AshOban do
state: :active | :paused | :deleted,
worker: module,
__identifier__: atom,
on_error: atom
on_error: atom,
cron?: boolean
}

defstruct [
Expand All @@ -38,6 +39,7 @@ defmodule AshOban do
:scheduler,
:worker,
:on_error,
:cron?,
:__identifier__
]

Expand Down Expand Up @@ -140,6 +142,12 @@ defmodule AshOban do
type: :atom,
doc:
"An update action to call after the last attempt has failed. See the getting started guide for more."
],
cron?: [
type: :boolean,
default: true,
doc:
"Whether to configure the scheduler and the Oban cron plugin to run the trigger on a cron schedule. Defaults to true."
]
]
}
Expand Down Expand Up @@ -252,7 +260,12 @@ defmodule AshOban do
end)
|> Enum.reduce(base, fn {resource, trigger}, config ->
require_queues!(config, resource, trigger)
add_job(config, cron_plugin, resource, trigger)

if trigger.cron? do
add_job(config, cron_plugin, resource, trigger)
else
config
end
end)
end

Expand Down
3 changes: 1 addition & 2 deletions lib/test.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ defmodule AshOban.Test do
@moduledoc "Helpers for testing ash_oban triggers"

def schedule_and_run_triggers(resource) do
triggers =
AshOban.Info.oban_triggers(resource)
triggers = AshOban.Info.oban_triggers(resource)

Enum.each(triggers, fn trigger ->
AshOban.schedule(resource, trigger)
Expand Down
10 changes: 8 additions & 2 deletions lib/transformers/define_schedulers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ defmodule AshOban.Transformers.DefineSchedulers do
|> Transformer.async_compile(fn ->
define_worker(module, worker_module_name, trigger, dsl)
end)
|> Transformer.async_compile(fn ->
define_scheduler(module, scheduler_module_name, worker_module_name, trigger, dsl)
|> then(fn dsl ->
if trigger.cron? do
Transformer.async_compile(dsl, fn ->
define_scheduler(module, scheduler_module_name, worker_module_name, trigger, dsl)
end)
else
dsl
end
end)
end)
|> then(&{:ok, &1})
Expand Down
3 changes: 2 additions & 1 deletion lib/transformers/set_defaults.ex
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ defmodule AshOban.Transformers.SetDefaults do
| read_action: read_action.name,
queue: queue,
scheduler_queue: trigger.scheduler_queue || queue,
action: trigger.action || trigger.name
action: trigger.action || trigger.name,
cron?: if(is_nil(trigger.cron?), do: true, else: trigger.cron?)
})
end)}
end
Expand Down
3 changes: 2 additions & 1 deletion test/ash_oban_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule AshObanTest do
doctest AshOban

defmodule Api do
use Ash.Api
use Ash.Api, validate_config_inclusion?: false

resources do
allow_unregistered? true
Expand All @@ -12,6 +12,7 @@ defmodule AshObanTest do

defmodule Triggered do
use Ash.Resource,
validate_api_inclusion?: false,
data_layer: Ash.DataLayer.Ets,
extensions: [AshOban]

Expand Down
233 changes: 233 additions & 0 deletions test/cron_flag_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
defmodule CronFlagTest do
use ExUnit.Case
doctest AshOban

defmodule Api do
use Ash.Api, validate_config_inclusion?: false

resources do
registry CronFlagTest.Registry
end
end

defmodule Registry do
use Ash.Registry

entries do
entry CronFlagTest.DefaultTrigger
entry CronFlagTest.CronTrigger
entry CronFlagTest.NonCronTrigger
end
end

defmodule DefaultTrigger do
use Ash.Resource,
validate_api_inclusion?: false,
data_layer: Ash.DataLayer.Ets,
extensions: [AshOban]

oban do
triggers do
api Api

trigger :process do
action :process
where expr(processed != true)
worker_read_action(:read)
end
end
end

actions do
defaults [:create]

read :read do
primary? true
pagination keyset?: true
end

update :process do
change set_attribute(:processed, true)
end
end

ets do
private? true
end

attributes do
uuid_primary_key :id
end
end

defmodule CronTrigger do
use Ash.Resource,
validate_api_inclusion?: false,
data_layer: Ash.DataLayer.Ets,
extensions: [AshOban]

oban do
triggers do
api Api

trigger :process do
action :process
where expr(processed != true)
worker_read_action(:read)
cron? true
end
end
end

actions do
defaults [:create]

read :read do
primary? true
pagination keyset?: true
end

update :process do
change set_attribute(:processed, true)
end
end

ets do
private? true
end

attributes do
uuid_primary_key :id
end
end

defmodule NonCronTrigger do
use Ash.Resource,
validate_api_inclusion?: false,
data_layer: Ash.DataLayer.Ets,
extensions: [AshOban]

oban do
triggers do
api Api

trigger :process do
action :process
where expr(processed != true)
worker_read_action(:read)
cron? false
end
end
end

actions do
defaults [:create]

read :read do
primary? true
pagination keyset?: true
end

update :process do
change set_attribute(:processed, true)
end
end

ets do
private? true
end

attributes do
uuid_primary_key :id
end
end

describe "Cron? flag" do
test "defaults to true if not provided" do
assert [%AshOban.Trigger{cron?: true}] = AshOban.Info.oban_triggers(DefaultTrigger)
end

test "is correctly set from DSL when provided" do
assert [%AshOban.Trigger{cron?: true}] = AshOban.Info.oban_triggers(CronTrigger)
assert [%AshOban.Trigger{cron?: false}] = AshOban.Info.oban_triggers(NonCronTrigger)
end

test "does not create scheduler module if set to false" do
refute Code.ensure_loaded?(NonCronTrigger.AshOban.Scheduler.Process)
end

test "creates scheduler module if not provided" do
assert Code.ensure_loaded?(DefaultTrigger.AshOban.Scheduler.Process)
end

test "creates scheduler module if set to true" do
assert Code.ensure_loaded?(CronTrigger.AshOban.Scheduler.Process)
end

test "does not configure a cron worker for trigger with cron? flag set to false" do
config =
AshOban.config([CronFlagTest.Api],
plugins: [
{Oban.Plugins.Cron, crontab: []}
],
queues: [
default_trigger_process: 1,
cron_trigger_process: 1,
non_cron_trigger_process: 1
]
)

plugins = config[:plugins]
cron = plugins[Oban.Plugins.Cron]
cron_tab = cron[:crontab]

refute Enum.any?(cron_tab, fn {_spec, module, _opts} ->
module == NonCronTrigger.AshOban.Scheduler.Process
end)
end

test "configures a cron worker for trigger with cron? flag set to true" do
config =
AshOban.config([CronFlagTest.Api],
plugins: [
{Oban.Plugins.Cron, crontab: []}
],
queues: [
default_trigger_process: 1,
cron_trigger_process: 1,
non_cron_trigger_process: 1
]
)

plugins = config[:plugins]
cron = plugins[Oban.Plugins.Cron]
cron_tab = cron[:crontab]

assert Enum.any?(cron_tab, fn {_spec, module, _opts} ->
module == CronTrigger.AshOban.Scheduler.Process
end)
end

test "configures a cron worker for trigger with cron? flag not provided" do
config =
AshOban.config([CronFlagTest.Api],
plugins: [
{Oban.Plugins.Cron, crontab: []}
],
queues: [
default_trigger_process: 1,
cron_trigger_process: 1,
non_cron_trigger_process: 1
]
)

plugins = config[:plugins]
cron = plugins[Oban.Plugins.Cron]
cron_tab = cron[:crontab]

assert Enum.any?(cron_tab, fn {_spec, module, _opts} ->
module == DefaultTrigger.AshOban.Scheduler.Process
end)
end
end
end
Loading