Skip to content

Instantly share code, notes, and snippets.

@tmaier
Last active April 1, 2023 22:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tmaier/0ae591bd871157a2650384be5903532b to your computer and use it in GitHub Desktop.
Save tmaier/0ae591bd871157a2650384be5903532b to your computer and use it in GitHub Desktop.
Dry::Transaction/dry-transaction enqueue step adapter

Enqueue Step Adapter for Dry-Transaction

The Dry::Transacation documenatation speaks of an enqueue step adapter in its documentation. However, I was unable to find a real world implementation.

This is why I came up with this in a PoC. I hope this is useful to someone.

How to use?

You must call #deliver_later or #perform_later yourself. enqueue will ensure, that it will be called after a potentially open ActiveRecord transaction has been finished.

around :transaction
step :do_fun_stuff_you_want_to_save
enqueue :send_welcome_email
step :do_other_cool_stuff

def send_welcome_email
  job = AccountMailer.welcome(user).deliver_later

  if job
    Success(job)
  else
    Failure()
  end
end

Dependencies

# frozen_string_literal: true
require 'after_commit_everywhere'
module CustomDryTransaction
class EnqueueAdapter
def call(step, _input, args)
operation = step.operation
result = if transaction_open?
AfterCommitEverywhere.after_commit(without_tx: :raise) do
operation.call(*args)
end
else
operation.call(*args)
end
Dry::Monads::Result(result)
end
private
def transaction_open?
ActiveRecord::Base.connection.transaction_open?
end
end
end
Dry::Transaction::StepAdapters.register :enqueue, CustomDryTransaction::EnqueueAdapter.new
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment