-
Notifications
You must be signed in to change notification settings - Fork 167
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
feat(keyv-mysql): use internal scheduler to delete expired keys #1291
Conversation
thanks. I would like to move forward with this but I am still reading up on events. Are there performance issues with events? |
@johaven I am wondering if we will want to all them to set the interval value? |
@jaredwray Scheduled events in MySQL are similar to stored procedures. So the performance is related to the queries that are executed. In this case, the query to remove expired keys is pretty simple, it shouldn't have any performance issues. That being said, I haven't tested on millions of keys. If the cache is a critical part of an application stack and it contains millions of entries I don't think you would choose MySQL in this case (although I think it would do the job well). On my side I use it for a cache on a medium sized application, it works very well, the scheduler runs every 5 minutes. The keys that are expired are filtered during get/mget/ops and cleaned later. You can check the state of the event with |
I ask myself the same question in this context, it is complicated to apply an interval that suits all needs, depending on the applications and the developers... That's why I thought we could leave the possibility of defining it. |
I think instead of doing We should also make sure that we can set it and overwrite the task if they change or update the settings. |
Good idea.
This is why i do |
It would also be more optimized to filter queries to handle the case where the record has not yet been purged by the scheduler. async get<Value>(key: string) {
const sql = `SELECT * FROM ${this.opts.table!} WHERE id = ? AND JSON_EXTRACT( value, '$.expiration' ) < UNIX_TIMESTAMP();` |
This would be useful if the expireInterval is turned on as otherwise it would grow without control |
@johaven - I added in the unit test and it looks like the event is not firing. Do you know why? |
@jaredwray I found a problem regarding the use of the mysql scheduler. SET GLOBAL event_scheduler = ON; This command may fail. There are 3 ways to make it work if it is not enabled by default :
|
I will try to test this week but on my side it works well (for other needs) edit: I forgot to cast the |
That's strange, I thought the key values were all serialized with an expires and value field. On my side I use cache-manager, that might be the reason. If we don't store the expiration, the scheduler can't do the job, I'll see about creating a timestamp field. edit: i created the |
There are still things to do:
|
@johaven - Yeah this unit test still fails and I made sure that it is passing the expires and wraps it. test.it('set intervalExpiration to 1 second', async t => {
const keyvMySql = new KeyvMysql({uri, intervalExpiration: 1});
const keyv = new Keyv({store: keyvMySql});
await keyv.set('foo-interval1', 'bar-interval1');
const value1 = await keyv.get('foo-interval1');
t.expect(keyvMySql.ttlSupport).toBe(true);
t.expect(value1).toBe('bar-interval1');
await delay(1100);
const value2 = await keyv.get('foo-interval1');
t.expect(value2).toBeUndefined();
}); |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1291 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 9 9
Lines 43 43
=========================================
Hits 43 43 ☔ View full report in Codecov by Sentry. |
@jaredwray There were still a few things to review, isn't it too early to merge the feature ? |
@johaven - i thought the last was documentation. Anything else? |
|
@johaven - ok. I wont be pushing a new build. Do you want me to do a pull request with these changes or are you working on it? |
@jaredwray This is not a big change, you should catch the error when you run the above command. For the error to be generated, you need to connect to the database with a user that does not have the "SUPER" privilege and change the ttlSupport to false (for this rollback, I don't know if it will be taken into account if it is changed at the time of connection, you must know better than me :) ). I don't have much time this week, I can work on it this weekend. |
Please check if the PR fulfills these requirements
** Proposal **
Currently a draft but works on all MySQL servers since version 5.1 (2008).
This uses the event_scheduler function (https://dev.mysql.com/doc/refman/8.4/en/create-event.html)
Activating ttlSupport becomes optional with my proposal, it might be necessary to be able to customize the interval but I find it an interesting alternative.
It's up to you to tell me if you want to validate the idea and we will finalize this PR