Envek / Envek/after_commit_everywhere

Flaky behavior in Minitest with callbacks and ActiveJob

Open
#19 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Ruby
Stars
789
Forks
23
PR merge metrics
No merged PRs in 30d

Description

Before anything else, I want to say thank you for this gem. It is awesome and very helpful in our code base.

Currently, I'm running into some flaky test behavior that I have narrowed down to this gem.

Use case: We have an ActiveRecord class for which do a 1:1 sync to an external service. Whenever we destroy a record, we want to enqueue a job to remove it from an external service.

```
class ExampleRecord < ApplicationRecord
after_destroy :sync_destroy_to_external_service

protected

def sync_destroy_to_external_service
ExternalServiceDeleteJob.perform_when_transaction_commits("some-key")
end
end

```

To enable this method, we have the following:

```
class ExternalServiceDeleteJob < ActiveJob::Base
extend AfterCommitEverywhere

def self.perform_when_transaction_commits(*args)
return perform_later(*args) unless in_transaction?

after_commit { perform_later(*args) }
end
end
```

We test this behavior in a really simple way:

```
test "enqueues destroy job on destruction" do
example_record = example_records(:some_fixture)
example_record.destroy!
assert_enqueued_with(job: ExternalServiceDeleteJob)
end
```

Nine out of ten times, this spec passes. However, on the random outlier, we get the following:

```
No enqueued job found with {:job=>ExternalServiceDeleteJob}
```

How I am really scratching my head. I suspect this has something to do with how `rails test` manages transaction.

Have you ever seen something like this before? Any idea on what might be causing it?

Thank you in advance for any guidance! And thank you again for this gem. Happy to contribute to a fix in anyway.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.