Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support limited cache size and automatic cleanup #13

Open
Qqwy opened this issue Dec 15, 2022 · 9 comments
Open

Support limited cache size and automatic cleanup #13

Qqwy opened this issue Dec 15, 2022 · 9 comments

Comments

@Qqwy
Copy link

Qqwy commented Dec 15, 2022

Hi there! This is a very well-written implementation of a SQL-based ActiveSupport::Cache::Store backend. 💚

By reading through the source code, I came across the cleanup method.

It seems like currently you'd have to call this manually. (Or e.g. put it in a whenever-based periodic task to make sure it happens ever so often).
Very much related, it might happen that the cache becomes very large (by being filled with many objects with no expires_in or one that is relatively far in the future).

It would be relatively straightforward to add the following two options:

  • A boolean auto_cleanup: option which, when true, will always (in an ensure block for good measure) call cleanup at the end of write_entry.
  • A positive-integermax_size: option which, when not-nil, will when calling write_entry while going over the limit, first run cleanup and if that is not enough, remove the oldest non-expired record (based on created_at).

What do you think?

I'd love to contribute a PR for these changes 👍 !

@Qqwy
Copy link
Author

Qqwy commented Dec 20, 2022

PR for the first option has been made: #14

@Qqwy
Copy link
Author

Qqwy commented Dec 20, 2022

And the second part can be found in #15

@dim
Copy link
Member

dim commented Dec 21, 2022

@Qqwy I have reviewed both PRs. As mentioned inline, I do see a use case for both, but I am a little hesitant to add them without further discussion as - although optional - seem to add quite a bit of overhead the average user may not want/be aware of. I have not seen any other cache backends implementing them, have you?

The #cleanup method is a bit of a beast as bulk deletes can be expensive. That's why - as you suggested - it is meant to be called via jobs, in the background. The cache is supposed to be quick, doing a cleanup on every write is going to have a heavily detrimental impact on performance. What do you think?

@dim
Copy link
Member

dim commented Dec 21, 2022

And thank you very much for the contribution, btw. It's really appreciated!

@skatkov
Copy link
Contributor

skatkov commented Jun 14, 2023

We're running into a similar issue -- our cache grows by huge margin and it seems to be happening because of expires_at is missing for a lot of records.

Screen Shot 2023-06-14 at 12 45 06

Screenshot 2023-06-14 at 12 53 47

It wouldn't be suitable for us to clean cache on write_entry as @dim already mentioned -- it will affect performance.

Instead, I was thinking of modifying cleanup method to introduce ability to purge records that are older than 1 month (this could be configurable). This could be determined based on created_at value.

@dim
Copy link
Member

dim commented Jun 15, 2023

@skatkov I can work with that, would you be able to submit a PR?

@dim dim mentioned this issue Jun 15, 2023
3 tasks
@dim
Copy link
Member

dim commented Jun 15, 2023

Alternatively, you could just have a background worker/task/job doing:

m = ActiveSupport::Cache::DatabaseStore::Model
m.where(m.arel_table[:updated_at].lt(1.month.ago)).delete_all

@skatkov
Copy link
Contributor

skatkov commented Jun 15, 2023

@dim will submit a PR with a fix.

@skatkov
Copy link
Contributor

skatkov commented Aug 25, 2023

Should we close this issue?

Here is PR that solved an issue at hand:
#24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants