mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-11 10:25:47 +02:00
feat(server): Introduce transaction clock.
Partially implements #6. Before, each shard lazily updated its clock used for the expiry evaluation. Now, the clock value is set during the transaction scheduling phase and is assigned to each transaction. From now on DbSlice methods use this value when checking whether the entry is expired via passed DbContext argument. Also, implemented transactionally consistent TIME command and verify that time is the same during the transaction. See https://ably.com/blog/redis-keys-do-not-expire-atomically for motivation. Still have not implemented any lamport style updates for background processes (not sure if it's the right way to proceed).
This commit is contained in:
parent
347a619b44
commit
0925829afb
28 changed files with 448 additions and 387 deletions
|
@ -106,18 +106,22 @@ void BlockingController::RunStep(Transaction* completed_t) {
|
|||
}
|
||||
}
|
||||
|
||||
DbContext context;
|
||||
context.time_now_ms = GetCurrentTimeMs();
|
||||
|
||||
for (DbIndex index : awakened_indices_) {
|
||||
auto dbit = watched_dbs_.find(index);
|
||||
if (dbit == watched_dbs_.end())
|
||||
continue;
|
||||
|
||||
context.db_index = index;
|
||||
DbWatchTable& wt = *dbit->second;
|
||||
for (auto key : wt.awakened_keys) {
|
||||
string_view sv_key = static_cast<string_view>(key);
|
||||
DVLOG(1) << "Processing awakened key " << sv_key;
|
||||
|
||||
// Double verify we still got the item.
|
||||
auto [it, exp_it] = owner_->db_slice().FindExt(index, sv_key);
|
||||
auto [it, exp_it] = owner_->db_slice().FindExt(context, sv_key);
|
||||
if (!IsValid(it) || it->second.ObjType() != OBJ_LIST) // Only LIST is allowed to block.
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue