Skip to content

Commit a649dca

Browse files
committed
Fixed expired key cleanup deleting concurrently refreshed values
The expired-entry cleanup in get() deleted by key alone, so between reading an expired row and issuing the delete, a set() on another instance could refresh the same key - and the delete would then remove the brand-new value, making a successful write silently vanish until the next set(). Scoping the delete to rows that are still expired closes the race; the periodic cleanup in set() already guards its delete the same way.
1 parent 3bf878a commit a649dca

1 file changed

Lines changed: 6 additions & 1 deletion

File tree

src/knex.kvstore.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,12 @@ export class KnexKvStore implements KvStore {
5858
`KnexKvStore: Deleting expired key ${key}`,
5959
keyInfo,
6060
);
61-
await this.knex(this.table).where(query).del();
61+
// Only delete if still expired - a concurrent set() may have
62+
// refreshed the row between our read and this delete
63+
await this.knex(this.table)
64+
.where(query)
65+
.where('expires', '<=', new Date())
66+
.del();
6267
return undefined;
6368
}
6469
if (row.value === null) {

0 commit comments

Comments
 (0)