@@ -14,6 +14,7 @@ extern "C" {
1414#include " redis/crc64.h"
1515}
1616
17+ #include " base/cycle_clock.h"
1718#include " base/flags.h"
1819#include " base/logging.h"
1920#include " redis/rdb.h"
@@ -33,6 +34,7 @@ extern "C" {
3334#include " server/set_family.h"
3435#include " server/tiered_storage.h"
3536#include " server/transaction.h"
37+ #include " util/fibers/fibers.h"
3638#include " util/fibers/future.h"
3739#include " util/varz.h"
3840
@@ -647,14 +649,16 @@ void OpScan(const OpArgs& op_args, const ScanOpts& scan_opts, uint64_t* cursor,
647649 PrimeTable::Cursor cur = *cursor;
648650 auto [prime_table, expire_table] = db_slice.GetTables (op_args.db_cntx .db_index );
649651
650- const auto start = absl ::Now ();
652+ const auto start_cycles = base::CycleClock ::Now ();
651653 // Don't allow it to monopolize cpu time.
652- const absl::Duration timeout = absl::Milliseconds (10 );
654+ // Approximately 15 microseconds.
655+ const uint64_t timeout_cycles = base::CycleClock::Frequency () >> 16 ;
653656
654657 do {
655658 cur = prime_table->Traverse (
656659 cur, [&](PrimeIterator it) { cnt += ScanCb (op_args, it, scan_opts, vec); });
657- } while (cur && cnt < scan_opts.limit && (absl::Now () - start) < timeout);
660+ } while (cur && cnt < scan_opts.limit &&
661+ (base::CycleClock::Now () - start_cycles) < timeout_cycles);
658662
659663 VLOG (1 ) << " OpScan " << db_slice.shard_id () << " cursor: " << cur.value ();
660664 *cursor = cur.value ();
@@ -666,7 +670,7 @@ uint64_t ScanGeneric(uint64_t cursor, const ScanOpts& scan_opts, StringVec* keys
666670
667671 EngineShardSet* ess = shard_set;
668672 unsigned shard_count = ess->size ();
669- constexpr uint64_t kMaxScanTimeMs = 100 ;
673+ constexpr uint64_t kMaxScanTimeMs = 25 ;
670674
671675 // Dash table returns a cursor with its right byte empty. We will use it
672676 // for encoding shard index. For now scan has a limitation of 255 shards.
@@ -686,10 +690,12 @@ uint64_t ScanGeneric(uint64_t cursor, const ScanOpts& scan_opts, StringVec* keys
686690 };
687691
688692 // Avoid deadlocking, if called from shard queue script
689- if (EngineShard::tlocal () && EngineShard::tlocal ()->shard_id () == sid)
693+ if (EngineShard::tlocal () && EngineShard::tlocal ()->shard_id () == sid) {
690694 cb ();
691- else
695+ util::ThisFiber::Yield ();
696+ } else {
692697 ess->Await (sid, cb);
698+ }
693699
694700 if (cursor == 0 ) {
695701 ++sid;
0 commit comments