Skip to content

Commit

Permalink
docs: update docs to remove bad example
Browse files Browse the repository at this point in the history
improvement: support destroy actions in the trigger action
improvement: debug logs
  • Loading branch information
zachdaniel committed Aug 31, 2023
1 parent 776eec9 commit 2ce62a5
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 70 deletions.
8 changes: 4 additions & 4 deletions documentation/tutorials/get-started-with-ash-oban.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ For example:
```elixir
oban do
triggers do
api YourApi
api YourApi
triggers do
# add a trigger called `:process`
trigger :process do
# this trigger calls the `process` action
action :process
# for any record that has `processed != true`
where expr(processed != true)
# checking for matches every minute
# checking for matches every minute
scheduler_cron "* * * * *"
on_error :errored
end
Expand All @@ -79,7 +79,7 @@ See the DSL documentation for more: `AshOban`
## Handling Errors
Error handling is done by adding an `on_error` to your trigger. This is an update action that will get the error as an argument called `:error`. The error will be an Ash error class. These error classes can contain many kinds of errors, so you will need to figure out handling specific errors on your own. Be sure to add the `:error` argument to the action if you want to receive the error.
Error handling is done by adding an `on_error` to your trigger. This is an update action that will get the error as an argument called `:error`. The error will be an Ash error class. These error classes can contain many kinds of errors, so you will need to figure out handling specific errors on your own. Be sure to add the `:error` argument to the action if you want to receive the error.
This is *not* foolproof. You want to be sure that your `on_error` action is as simple as possible, because if an exception is raised during the `on_error` action, the oban job will fail. If you are relying on your `on_error` logic to alter the resource to make it no longer apply to a trigger, consider making your action do *only that*. Then you can add another trigger watching for things in an errored state to do more rich error handling behavior.
Expand Down
9 changes: 9 additions & 0 deletions lib/ash_oban.ex
Original file line number Diff line number Diff line change
Expand Up @@ -356,4 +356,13 @@ defmodule AshOban do
"""
end
end

@doc false
def update_or_destroy(changeset, api) do
if changeset.action.type == :update do
api.update(changeset)
else
api.destroy(changeset)
end
end
end
64 changes: 51 additions & 13 deletions lib/transformers/define_schedulers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,36 @@ defmodule AshOban.Transformers.DefineSchedulers do
insert =
if pro? do
quote location: :keep do
def insert(stream) do
stream
|> Stream.chunk_every(100)
|> Stream.each(&Oban.insert_all/1)
|> Stream.run()
defp insert(stream) do
count =
stream
|> Stream.chunk_every(100)
|> Stream.map(fn batch ->
Oban.insert_all(batch)
Enum.count(batch)
end)
|> Enum.sum()

Logger.debug(
"Scheduled #{count} jobs for trigger #{unquote(inspect(resource))}.#{unquote(trigger.name)}"
)

:ok
end
end
else
quote location: :keep do
def insert(stream) do
stream
|> Stream.each(&Oban.insert!/1)
|> Stream.run()
defp insert(stream) do
count =
stream
|> Stream.each(&Oban.insert!/1)
|> Enum.count()

Logger.debug(
"Scheduled #{count} jobs for trigger #{unquote(inspect(resource))}.#{unquote(trigger.name)}"
)

:ok
end
end
end
Expand Down Expand Up @@ -370,18 +387,36 @@ defmodule AshOban.Transformers.DefineSchedulers do
|> Ash.Query.for_read(unquote(read_action))
|> unquote(api).read_one()
|> case do
{:error, error} ->
{:error, error}

{:ok, nil} ->
Logger.debug(
"Record with primary key #{inspect(primary_key)} no longer applies to trigger #{unquote(inspect(resource))}#{unquote(trigger.name)}"
)

{:discard, :trigger_no_longer_applies}

{:ok, record} ->
record
|> Ash.Changeset.new()
|> prepare_error(primary_key)
|> Ash.Changeset.set_context(%{private: %{ash_oban?: true}})
|> Ash.Changeset.for_update(unquote(trigger.on_error), %{error: error})
|> unquote(api).update()
|> Ash.Changeset.for_action(unquote(trigger.on_error), %{error: error})
|> AshOban.update_or_destroy(unquote(api))
|> case do
:ok ->
Logger.debug(
"Performed #{unquote(trigger.action)} on #{inspect(primary_key)} no longer applies to trigger #{unquote(inspect(resource))}#{unquote(trigger.name)}"
)

:ok

{:ok, result} ->
Logger.debug(
"Performed #{unquote(trigger.action)} on #{inspect(primary_key)} no longer applies to trigger #{unquote(inspect(resource))}#{unquote(trigger.name)}"
)

:ok

{:error, error} ->
Expand Down Expand Up @@ -454,9 +489,12 @@ defmodule AshOban.Transformers.DefineSchedulers do
|> Ash.Changeset.new()
|> prepare(primary_key)
|> Ash.Changeset.set_context(%{private: %{ash_oban?: true}})
|> Ash.Changeset.for_update(unquote(trigger.action), %{})
|> unquote(api).update()
|> Ash.Changeset.for_action(unquote(trigger.action), %{})
|> AshOban.update_or_destroy(unquote(api))
|> case do
:ok ->
:ok

{:ok, result} ->
{:ok, result}

Expand Down
55 changes: 2 additions & 53 deletions test/ash_oban_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,8 @@ defmodule AshObanTest do
use ExUnit.Case
doctest AshOban

defmodule Api do
use Ash.Api

resources do
allow_unregistered? true
end
end

defmodule Triggered do
use Ash.Resource,
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

trigger :process_2 do
action :process
where expr(processed != true)
worker_read_action(:read)
scheduler_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
alias AshOban.Test.Api
alias AshOban.Test.Triggered

test "foo" do
assert [
Expand Down
7 changes: 7 additions & 0 deletions test/support/api.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule AshOban.Test.Api do
use Ash.Api

resources do
allow_unregistered? true
end
end
45 changes: 45 additions & 0 deletions test/support/triggered.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
defmodule AshOban.Test.Triggered do
use Ash.Resource,
data_layer: Ash.DataLayer.Ets,
extensions: [AshOban]

oban do
api AshOban.Test.Api

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

trigger :process_2 do
action :process
where expr(processed != true)
worker_read_action(:read)
scheduler_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

0 comments on commit 2ce62a5

Please sign in to comment.