snapshot-labs / sx-ui

An open source interface for Snapshot X protocol.
https://snapshotx.xyz
MIT License
34 stars 29 forks source link

fix: invalidate Stamp cache when changing avatars #640

Closed Sekhmet closed 1 year ago

Sekhmet commented 1 year ago

@bonustrack

From Notion:

Maybe we should allow cache to depend on some v query param so we can version avatar changes and fetch latest one?

We do that on Snapshot, there is a param “cb” that you can add on stamp image URLs, cb stand for cache buster, we use a hash of the avatar image URL for the value. Example: https://cdn.stamp.fyi/space/fabien.eth?s=160&cb=b7fd812c7341f97e

What about the AWS cache on stamp? It doesn't depend on cb query, only type, network, address, w, h and fallback. So even with cb we can be using old AWS cache?

bonustrack commented 1 year ago

Wouldn't this cache be overwrited? If not there is maybe some change to do in Stamp. When I try to change an avatar on snapshot.org space it doesn't show the new avatar directly, it seem to use a cache but the backend seem to react properly.

Sekhmet commented 1 year ago

@bonustrack from what I understand we store files on AWS forever so I don't understand how it would ever not use it anymore. That's why I was asking if we have some expiration for AWS, because otherwise it doesn't make sense - I assumed that's the way we wanted it to work for some reason.

Maybe it worked before, because cache was broken (https://github.com/snapshot-labs/stamp/pull/39) - but it would still use cached (original) image from AWS before this PR, it would just keep resizing it on each request.

For example this avatar returns outdated avatar, unless you clear /clear https://stamp.fyi/space-sx/0x65e4329e8c0fba31883b98e2cf3e81d3cdcac780?s=180&cb=20000000 (updated image, but not the latest) this is the actual image it should return now: https://ipfs.io/ipfs/bafkreih7gpbvmiqgzkzwwhwo2a5ritsezhx4jofvp7pcjdvlf7rv7uss64

If it's not the way we expect it to work then Stamp needs some architectural changes.

bonustrack commented 1 year ago

@Sekhmet There is not expiration with AWS, we generate key1 based on type, network, address, w, h and fallback. In key1 the w and h are always 500. This key become a folder and within this folder we store the different resize as cache. When you call /clear it will delete the whole folder, so the next time you query it wont use the cache. We also have a browser cache set with Cache-Control header which should get reset if you change the cb. This is supposed to work this way but there might be some issues if it doesn't react this way.

Sekhmet commented 1 year ago

Cache-Control only controls how device should cache it (we probably should also use edge-cache so it gets cached by Cloudflare for all users). If we change cb parameter it's considered different URL so cache no longer applies.

Simplified example how it currently operates (ignoring resizing)

  1. user fetches https://cdn.stamp.fyi/space-sx/0x65e4329e8c0fba31883b98e2cf3e81d3cdcac780?cb=1
  2. we generate hash: hash(type, network, address, w, h) = 40e28e71262fc8f75aeaf1e271408a4b14593e25f963259fe329f384b05833f0
  3. there is no match in AWS, we fetch it from SnapshotX subgraph, load and store it under 40e28e71262fc8f75aeaf1e271408a4b14593e25f963259fe329f384b05833f0 key on AWS
  4. we return newly fetched image to the user, setting Cache-Control so user's browser caches it
  5. user fetches https://cdn.stamp.fyi/space-sx/0x65e4329e8c0fba31883b98e2cf3e81d3cdcac780?cb=1 again, it gets returned from browser's cache directly
  6. we assume that avatar has changed, so cb gets changed as well, user fetches https://cdn.stamp.fyi/space-sx/0x65e4329e8c0fba31883b98e2cf3e81d3cdcac780?cb=2
  7. this is different URL so browser cache doesn't apply, we hit the server:
  8. we generate hash: hash(type, network, address, w, h) = 40e28e71262fc8f75aeaf1e271408a4b14593e25f963259fe329f384b05833f0 THIS IS THE SAME HASH AS BEFORE
  9. as it's the same we will return persisted image from AWS - this is old image, not the new one we expect

In my opinion how it should work is: a. we drop AWS and just use edge-cache (this way cloudflare caches responses globally for all our users), we get rid of extra complexity in the code and extra dependency. b. we include cb in key generation for AWS files - this way when we change cb we will ignore AWS cache for different avatars. c. combine a. and b if we are concerned by reliability of resolvers (AWS is global, edge-cache is per region so there is a risk of resolver failing for one region so some users might see fallback and some will see real avatar).

Sekhmet commented 1 year ago

@bonustrack PR with b) implemented: https://github.com/snapshot-labs/stamp/pull/55