2929#include < thread>
3030#include < utility>
3131
32+ #include " common/task_runner.h"
3233#include " db_util.h"
3334#include " logging.h"
3435#include " parse_util.h"
@@ -680,6 +681,7 @@ rocksdb::Status Hash::PersistFields(engine::Context &ctx, const Slice &user_key,
680681}
681682
682683void Hash::asyncRepairHash (const std::string &ns_key, const Slice &field, const HashMetadata &metadata) const {
684+ // Use the server's task runner to schedule the repair task instead of spawning a thread.
683685 auto repair_task = [storage = storage_, ns_key, field_str = field.ToString (), version = metadata.version ,
684686 size = metadata.size ]() {
685687 if (size == 0 ) {
@@ -689,27 +691,20 @@ void Hash::asyncRepairHash(const std::string &ns_key, const Slice &field, const
689691 engine::Context ctx (storage);
690692 std::string sub_key = InternalKey (ns_key, field_str, version, storage->IsSlotIdEncoded ()).Encode ();
691693
692- // Use a retry loop to implement optimistic locking. This is to atomically
693- // decrement the hash size and prevent a race condition when multiple threads
694- // are repairing the same hash.
695694 for (int i = 0 ; i < 10 ; ++i) {
696695 HashMetadata current_metadata (false );
697696 std::string metadata_bytes;
698697 auto s = storage->Get (ctx, ctx.GetReadOptions (), storage->GetCFHandle (ColumnFamilyID::Metadata), ns_key,
699698 &metadata_bytes);
700699 if (!s.ok ()) {
701- // If metadata is not found, another repair might have cleaned it up. Stop.
702700 if (s.IsNotFound ()) return ;
703- // For other errors, log and stop.
704701 error (" Failed to get metadata for async repair: {}" , s.ToString ());
705702 return ;
706703 }
707704 if (!current_metadata.Decode (metadata_bytes).ok ()) {
708705 error (" Failed to decode metadata for async repair" );
709706 return ;
710707 }
711-
712- // If size is already 0, no need to decrement.
713708 if (current_metadata.size == 0 ) return ;
714709
715710 auto batch = storage->GetWriteBatchBase ();
@@ -728,7 +723,10 @@ void Hash::asyncRepairHash(const std::string &ns_key, const Slice &field, const
728723 error (" Failed to async repair hash field after multiple retries" );
729724 };
730725
731- std::thread (repair_task).detach ();
726+ // Use the server's task runner and TryPublish
727+ if (server_ && server_->GetTaskRunner ()) {
728+ server_->GetTaskRunner ()->TryPublish (std::move (repair_task));
729+ }
732730}
733731
734732} // namespace redis
0 commit comments