-
Notifications
You must be signed in to change notification settings - Fork 694
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
Incr expired_keys if the expiration time is already expired #1517
base: unstable
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## unstable #1517 +/- ##
============================================
+ Coverage 70.82% 70.85% +0.03%
============================================
Files 120 120
Lines 64911 64915 +4
============================================
+ Hits 45972 45995 +23
+ Misses 18939 18920 -19
|
The core of this issue is whether we should consider setting an expired time for a key as a delete operation or an expiration. I believe it should be considered as expiration because the user's intended action is to set an expire time for the key. However, due to some reasons (such as operational delays), the time has already passed. Nonetheless, the key is still deleted due to expiration. Therefore, in terms of statistics and notifications, it should be counted as expiration-based deletion. Additionally, we have already sent notifications regarding the expiration for the module: void deleteExpiredKeyFromOverwriteAndPropagate(client *c, robj *keyobj) {
int deleted = dbGenericDelete(c->db, keyobj, server.lazyfree_lazy_expire, DB_FLAG_KEY_EXPIRED);
int dbGenericDelete(serverDb *db, robj *key, int async, int flags) {
int dict_index = getKVStoreIndexForKey(key->ptr);
return dbGenericDeleteWithDictIndex(db, key, async, flags, dict_index);
}
int dbGenericDeleteWithDictIndex(serverDb *db, robj *key, int async, int flags, int dict_index) {
hashtablePosition pos;
void **ref = kvstoreHashtableTwoPhasePopFindRef(db->keys, dict_index, key->ptr, &pos);
if (ref != NULL) {
robj *val = *ref;
/* VM_StringDMA may call dbUnshareStringValue which may free val, so we
* need to incr to retain val */
incrRefCount(val);
/* Tells the module that the key has been unlinked from the database. */
moduleNotifyKeyUnlink(key, val, db->id, flags); However, there is a change here: the notification has been changed from |
Signed-off-by: Ray Cao <[email protected]>
18efebb
to
aafe746
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall make sense to me.
Signed-off-by: Ray Cao <[email protected]>
Yeah, I think at the very least this needs to be marked as a breaking change, since we are changing the event type. Even if the new behavior is more correct, it's such a long standing behavior someone might have coded around it. |
This PR modifies two parts of the
deleteExpiredKeyFromOverwriteAndPropagate
function, which is called when the expiration time has already expired.GENERIC-del
toEXPIRED-expired
.Since this delete operation is triggered by EXPIRE, and the flag pass to
dbGenericDeleteWithDictIndex
isDB_FLAG_KEY_EXPIRED
, which is used to notify module, maybe we should align the behavior and send Keyspace Event notify likedeleteExpiredKeyAndPropagateWithDictIndex
did.server.stat_expiredkeys
in this case could more accurately reflect the number of keys deleted due to expiration.