Example Documentation for ash_oban

I’m looking at ash_oban and was trying to understand setting up a worker and using schedule/2 or run_trigger/2 to specify a resource to reference for processing (I had Oban previously outside of Ash).

The provided tests in the repo only really show that a trigger is able to be read and the existing documentation doesn’t go beyond setting up Oban; “Usage” only discusses setting up a trigger but not using it.

Any examples of actually processing a worker from a trigger and invoking a trigger would be helpful.

Hey there! Unfortunately we can’t test it the way we want to because we can’t get a license for Oban pro, but its currently in use in multiple apps so even though the automated testing is light, its being battle tested as we speak.

So, generally speaking you don’t need to use run_trigger/2. The way it works is that there is a scheduler_cron (which currently defaults to every one minute i.e "* * * * *") that runs the update action for every record matching its where option (which by default is everything). For example:

trigger :processing do
  action :process
  where expr(processed != true)
  scheduler_cron "* * * * *"
  on_error :errored
end

That example is the one from the docs. So that trigger essentially uses itself, assuming you’ve followed the guide and set up the Oban guide.

There are two ways you might enqueue a job manually. Keep in mind it still has to match the conditions listed on the trigger, but it it can basically let you enqueue something without waiting for the scheduler. The first one is using change run_oban_trigger/ from the action. For example, we might have an action:

update :reprocess do
  accept []
  change set_attribute(:processed, false)
  change run_oban_trigger(:process)
end

That enqueues the job to process an item immediately, instead of waiting for the scheduler to run and enqueue the job (since it now matches processed != true, it will get picked up on the next run of the scheduler).

The other way you can do essentially the same thing is with AshOban.run_trigger/2. This version is when you want to do it dynamically, say something like:

# perhaps in testing or for some reason you have a record and you want to run some trigger
AshOban.run_trigger(some_record, :trigger_name)

Keep in mind those two manual versions are only necessary if you want to run a trigger manually. The scheduler will run and schedule jobs matching the conditions of the trigger automatically otherwise.

Disabling the schduler

You can also configure scheduler_cron false. This lets you set up a trigger that will never be automatically scheduled. In which case you will need to do one of the two things listed above to schedule a trigger.

Hopefully that helps! That is a pretty new package, and is definitely very sparse on docs :slight_smile:

2 Likes

Thanks! For worker_read, does that essentially perform a query against what is intended to be sent to the worker? And are workers set up the same way as regular Oban workers or do they need to be done in the context of the AshOban resource as an action? Any pointers here would be greatly appreciated.

For context, I will typically have a lot of jobs that need to be manually scheduled to run once in the future.

Under the hood: the scheduler finds any records that match using the read action and the where clause, and then enqueues a job for the worker with that record’s primary key. Then, when the worker runs, it uses the read action and the where clause and the primary key to find the record in question. This helps ensure that if a record is no longer matching the condition for processing, that it won’t be processed. You can customize that worker read action, but generally you don’t need to.

Workers themselves are standard Oban workers, that expect a "primary_key" argument to be given that identifies an instance of a record. Its not very easy to read, and I’d like to add some tooling to see what the generated modules look like (or to generate them into your app for easier reading), but here is where we define those modules: https://github.com/ash-project/ash_oban/blob/v0.1.9/lib/transformers/define_schedulers.ex

I have a feeling I haven’t quite answered your question though, so please LMK if that doesn’t clarify things :smiley:

Edit: just took on slack, we cant delete our own posts here?