How to trigger multiple resources oban definitions from one location?

im trying to trigger multiple resources oban definitions from one location, obv this is wrong. heres an example , basically i need to have an update run across multiple resources and to my knowledge when i trigger oban it runs the default read query then preforms the action on all the results? do i just make a calculation on each module and run it ?

defmodule settings do 
...
update :update do
  require_atomic? false
   argument :currency, :string, default: "EUR"
  change set_attribute(:currency, arg(:currency))

  change {AssignCurrency, [currency: arg(:currency)]}
end

defmodule AssignCurrency
use Ash.Resource.Change
...
  import Ash.Expr

  alias Ash.Changeset
  alias Ash.NotLoaded
  alias Ash.Query

  @modules [Modulename]

  @impl true
  def change(changeset, opts, _context) do
    currency = opts[:currency]
      Enum.map(@modules, fn(m) ->
       AshOban.Info.oban_trigger(m, :process)
   end)

 
end

defmodule Modulename do
...
update :change_currency do
      accept []

      argument :currency, :string

      change set_attribute(:currency, currency)
    end

    update :oban do
      accept []
      argument :currency, :string

      change set_attribute(:currency, arg(:currency))

      change run_oban_trigger(:process)
    end

oban do
    triggers do
      trigger :process do
        action :change_currency
        worker_read_action(:read)
      end
    end

    domain System
  end
end

The way you are doing it is correct, but I think what you likely want is to set:

scheduler_cron false

to avoid the scheduler from doing what you described.

Triggers are designed to essentially automatically find data that should trigger them, and then running the update action.

EDIT:

Sorry, not quite correct. You should use AshOban.run_trigger not AshOban.Info.oban_trigger. And you should do it in a before or after action hook :slight_smile:

1 Like

im still not quite there yet. i placed the after action like such, it is an issue that the first arg on the process trigger is the modulename not the record? it seems not to be hitting the triggers. im using craftplan as a learning example my repo is GitHub - data-twister/craftplan: Self-hosted software for managing artisanal D2C micro-businesses change i made is to the assign_currency.ex file

  def change(changeset, opts, _context) do

    Ash.Changeset.after_action(changeset, fn _changeset, record ->
      currency = opts[:currency]
      Enum.map(@modules, fn(m) ->
        AshOban.run_trigger(m, :process)
      end)
      {:ok, record}
    end)

    changeset
  end

Are you doing this in tests? Those jobs won’t execute immediately, they are queued and in test they only execute when you tell them to.

I just wrote and published a new testing guide that you may find useful: Testing — ash_oban v0.7.2

no but im watching the db and the oban_jobs table never gets populated. i put a link to my repo so i dont have to write snippets, if i run the trigger from the action it all works, but it only hits the trigger defined in the module, i wanted to run triggers on diff modules. as there are multiple schemas that data needs the update, is this not working becauyse i have the trigger in a custom changeset under the change function?? i followed the test examples but still nothing

:thinking: no the pattern you’re doing is very common, but I’m not following what you mean about running triggers on different modules. The way AshOban triggers work is that they model what is effectively a “find and update” loop, with the ability to trigger just the “update” part on-demand for records. So I’m not sure what you mean about trying to run triggers on different modules. You’d need a record for the other resource in question to run those triggers on it.

So like you might say AshOban.run_trigger(a_specific_user, :send_welcome_email).

As for not having to write snippets: that is a big repo with 15 commits in your fork different from the base for me to read through to find specifically what you’re doing, and I’m not personally familiar with the craft plan codebase so its really just an entirely separate codebase. I’m more than happy to help here, but I just don’t have the time to do the work involved in figuring out which parts of that codebase are at play etc.


EDIT: I think perhaps I understand what you mean though, now. You want to trigger all matching records for some given resource to be processed? You can use AshOban.schedule_and_run_triggers to run the entire scheduler logic for any given trigger on a module (similar to the testing utility). I’m not sure of a case where it really makes sense to do that, though, so I’m wondering if perhaps we’re having a bit of an xy problem and maybe you should instead be telling me what you’re actually trying to accomplish.

yup thats what i needed just needed a lil massaging, thx again

1 Like