Make sure jobs are enqueued only after all transactions are committed

This should fix the recurring ActiveStorage::FileNotFoundError errors
from ActiveStorage::AnalyzeJob.

The issue is that, when images are not direct uploaded (e.g. a card
background image or avatar image), the AnalyzeJob has been getting
enqueued before the file itself was uploaded to blob storage.

Setting ActiveJob::Base.enqueue_after_transaction_commit = true makes
sure that jobs are always enqueued only once *all* transactions have
been committed.

This will be the Rails default at some point, but for now we still
need to explicitly set it.

Big thanks to @jeremy for the assist. 👏
This commit is contained in:
Mike Dalessio
2025-11-20 18:47:42 -05:00
parent fdee7aaaa5
commit 2c2a1c4b4a
2 changed files with 1 additions and 23 deletions
@@ -1,23 +0,0 @@
# Avoid sporadic ActiveStorage::FileNotFoundError errors
#
# Our direct-uploads aren't really direct. They first get buffered by CloudFlare
# and then get sent to our storage servers. This can lead to situations where
# a form was submitted, and ActiveStorage::Attachment created, and an
# AnalyzeJob enqueued, but the file associated with the Blob doesn't yet exist
# in our storage service.
#
# A simple olution ot this problem is just to retry the job a few times with
# some backoff.
#
# Discussion: https://app.fizzy.do/5986089/cards/3056
module ActiveStorageAnalyzeJobRetires
extend ActiveSupport::Concern
included do
retry_on ActiveStorage::FileNotFoundError, attempts: 15, wait: 2.seconds
end
end
ActiveSupport.on_load :active_storage_blob do
ActiveStorage::AnalyzeJob.prepend ActiveStorageAnalyzeJobRetires
end