silverstripe / silverstripe-s3

Silverstripe module to store assets in S3 rather than on the local filesystem (SS4/SS5 only)
BSD 3-Clause "New" or "Revised" License
20 stars 25 forks source link

Skip the cache #32

Closed phptek closed 4 years ago

phptek commented 4 years ago

In a project of ours running 1.0, we still seem to be experiencing the same problem outlined in #19 and that was supposedly fixed in 0.4.0.

Question: What ae the ramifications of entirely removing the cache that seems to be at fault? We're not talking exceedingly high traffic here. As a side note, what is the recommended approach (if there is one) for switching out the cache for a different one that uses e.g. Memcache/Redis via AWS ElastiCache?

obj63mc commented 4 years ago

If you are seeing issues with the cache I would check the /tmp folder (Unix based os) where silverstripe outputs all the cache folders for your project. You could try deleting the temp ss folder and see if that resolves the issue or I'd make sure there are no weird write permissions that could keep the cache from generating/updating properly. You could also overwrite the _config/assets.yml file of this project in your project's app.yml to change the folder where the cache is written or how it is written. If you wanted to use redis or something else from League's flysystem caching options that is where you would configure it.

As to skipping the cache, just setting the adapters used by silverstripe to the non cached versions (PublicAdapter instead of PublicCachedAdapter...) should then skip the cache. In terms of performance issues, with out the cache essentially all urls have to be regenerated constantly for each image object, whether public or protected so if you are on a page that has a lot of images (say asset admin in the CMS) it will probably run extremely slow.

grantpatterson commented 4 years ago

I work with @phptek. I think the key factor here is that this is a clustered environment with two SilverStripe instances. Currently each instance has it's own independent cache in its local tmp folder.

After uploading an image and publishing this can result in one instance's cache saying the image is published while the other says it's protected. This can then result in a broken image URL, depending on which instance subsequent website users hit.

If we continue using the cached versions of the adapters, I think they need to be using a cache store shared by all nodes in the cluster.

obj63mc commented 4 years ago

My recommendation then would be to use a predis or memcached adapter like the examples in https://flysystem.thephpleague.com/docs/advanced/caching/

In your local project you can extend the PublicCachedAdapter and PrivateCachedAdapter constructors to create the redis client or memcache client and then return the new cacheadapter instance.

You would then just have to set up your yml config to use this new custom cache adapter.

phptek commented 4 years ago

@obj63mc Thanks for the quick responses. We should be able to figure out an alternative cache implementation, using the default classes & config as a template.

However - should we wish to try and skip the cache entirely, we'd obviously need to override the module's YML config. From what you can tell, would the following work, without the additional constructor params etc?

We appreciate the potential for performance issues in the CMS' asset-admin, however, we're talking in the order of 10's of images, so we don't ancticiapte this to be a problem.

---
Name: my-app-s3-config
After:
  - '#silverstripes3-flysystem'
---

  SilverStripe\Assets\Flysystem\PublicAdapter:
    class: SilverStripe\S3\Adapter\PublicAdapter
  SilverStripe\Assets\Flysystem\ProtectedAdapter:
    class: SilverStripe\S3\Adapter\ProtectedAdapter
obj63mc commented 4 years ago

I haven't tested it but yes I believe that would work, you would just need to have -

SilverStripe\Core\Injector\Injector:

before the rest of the settings so -

SilverStripe\Core\Injector\Injector:
  SilverStripe\Assets\Flysystem\PublicAdapter:
    class: SilverStripe\S3\Adapter\PublicAdapter
  SilverStripe\Assets\Flysystem\ProtectedAdapter:
    class: SilverStripe\S3\Adapter\ProtectedAdapter