collectiveidea / delayed_job

Database based asynchronous priority queue system -- Extracted from Shopify
http://groups.google.com/group/delayed_job
MIT License
4.82k stars 954 forks source link

DelayedJob cannot find a CarrierWave uploader class #1221

Open tsung-yen-tsai-galvanize opened 1 month ago

tsung-yen-tsai-galvanize commented 1 month ago

Hi, I'm not sure if this is the appropriate place to post this, but it seems like an issue. I am running into this error:

Job Delayed::PerformableMethod (id=3200623) (queue=default) FAILED permanently with Delayed::DeserializationError: Job failed to load: undefined class/module LogoUploader::WebVersionUploader.

I think this class is dynamically generated by CarrierWave using const_set, it seems like from here: https://github.com/carrierwaveuploader/carrierwave/blob/a5518d6ae6d2cd1dc12776fe76ac49b8ccf6d551/lib/carrierwave/uploader/versions.rb#L23 (we are using an older version, with slightly different name). Is there a way to autoload this constant so that DelayedJob can pick it up? I've tried require 'carrierwave' and require 'carrierwave/versions' in application.rb, and it does not help. We are using DelayedJob 4.1.11. Please let me know if any other details would help with this, or is it a limitation of DelayedJob and dynamically generated classes/methods? I've noticed a similar error for attr_accessor as well.

albus522 commented 4 weeks ago

If you are trying to background an upload, you should never do that in any background job processor.

tsung-yen-tsai-galvanize commented 4 weeks ago

Hi @albus522 , thank you for the quick reply. We are not trying to background an upload actually, we are emitting an EventBridge event (related to an organization being updated) in the background. This event has recently been updated to include a previous_state, which is required for audit purposes (and to calculate the changed attributes). This previous_state is basically a copy of the Organization ActiveRecord object in a plain Ruby class/object, but is not saved (as a workaround for this: https://github.com/collectiveidea/delayed_job/wiki/Common-problems#dj-doesnt-deserialize-an-unsaved-activerecord-model). One of the attributes on this copy is a logo, which is a object with an attribute that contains the LogoUploader::WebVersionUploader that's causing issues. Is this something that should be doable with DelayedJob?

albus522 commented 4 weeks ago

Serializing an unsaved record is not going to work the way you want. It will be loaded as a fresh copy from the database at a step after the error you are currently hitting.

tsung-yen-tsai-galvanize commented 4 weeks ago

The previous_state organization's attributes is copied to an plain Ruby object, so hopefully it skips the database loading step as it is not an ActiveRecord object. It seems to work to send the event with Delayed Job when the organization has no logo: image But if the organization has a logo, we run into the problem in the OP.