How to handle signed S3 image url expiration in Elasticsearch in and Rails 7

144 Views Asked by At

I am using AWS S3 with Rails 7 to store images via Active Storage. I'm presenting my data to the view by querying Elasticsearch (using the elasticsearch-model gem). While this works great for my other data, the expiration of the signed AWS URL becomes an issue after a little while and the images are of course no longer accessible.

class MyClass
  has_one_attached :image
end

I'd like to be able to have a fresh URL and still use Elasticsearch so that I don't need to make a trip to the database every time I want to see the image.

I have looked up whether I can just remove the expiration however I've read that it's unsafe and mostly unsupported. I know that Elasticsearch::Model callbacks exists but I'm not clear on whether that could be applied to ActiveStorage::Blob, especially since nothing changes in the DB when the expiration occurs.

I've also thought about just changing the URLs to expire at 1 week via passing in the expires_in param to the url method on the attachement and then performing a chon job to update the image once a week. Seems hacky though.

1

There are 1 best solutions below

0
On

I'm sure there are many ways to approach this but what worked for me was using the save callback on an async job when the model that contains the Elasticsearch::Model. When this particular attribute was updated, I called a job with a delay just before the maximum signed_url time allowed by s3 which is 7 days.

   after_save :set_refresh_url_job, if: Proc.new { logo_url? }
  def set_refresh_url_job
    RefreshLogoUrlJob.
      set(wait: MyModel::LOGO_EXPIRTY_REFRESH).
      perform_later(self)
  end