Search code examples
rubyshrine

Extracting image dimensions in the background with Shrine


I have set up direct uploads to S3 with Shrine. This works great. Among others, I have the following plugins enabled:

Shrine.plugin :backgrounding
Shrine.plugin :store_dimensions 
Shrine.plugin :restore_cached_data

Correct me if I'm wrong but image dimensions extraction appears to be done synchronously. If I let the user bulk upload images via Uppy and then persist them all, this seems to be taking a long time.

What I'd like to do is perform image dimensions extraction asynchronously - I don't need the dimensions available for the cached file. If possible, I'd like to do that in the background when the file gets promoted to the store. Is there a way to do it?


Solution

  • The way I got this to work is by making use of :refresh_metadata plugin, instead of :restore_cached_data which I used originally. Thanks to Janko for pointing me in the right direction.

    Reading into the source code provided some useful insights. :store_dimensions plugin by itself doesn't extract dimensions - it adds width and height to the metadata hash so that when Shrine's base class requests metadata, they get extracted too.

    By using :restore_cached_data, this was being done on every assignment. :restore_cached_data uses :refresh_metadata internally so we can use that knowledge to only call it when the file is promoted to the store.

    I have :backgrounding and :store_dimensions set up in the initializer so the final uploader can be simplified to this:

    class ImageUploader < Shrine
      plugin :refresh_metadata
      plugin :processing
    
      process(:store) do |io, context|
        io.refresh_metadata!(context)
        io
      end
    end
    

    This way persisting data we get from Uppy is super fast and we let the background job extract dimensions when the file is promoted to the store, so they can be used later.

    Finally, should you have questions related to Shrine, I highly recommend its dedicated Google Group. Kudos to Janko for not only creating an amazing piece of software (seriously, go read the source), but also for his dedication to supporting the community.