@@ -14,11 +14,13 @@ namespace ErrorCodes
1414StorageObjectStorageStableTaskDistributor::StorageObjectStorageStableTaskDistributor (
1515 std::shared_ptr<IObjectIterator> iterator_,
1616 std::vector<std::string> && ids_of_nodes_,
17- bool send_over_whole_archive_)
17+ bool send_over_whole_archive_,
18+ uint64_t lock_object_storage_task_distribution_ms_)
1819 : iterator(std::move(iterator_))
1920 , send_over_whole_archive(send_over_whole_archive_)
2021 , connection_to_files(ids_of_nodes_.size())
2122 , ids_of_nodes(std::move(ids_of_nodes_))
23+ , lock_object_storage_task_distribution_us(lock_object_storage_task_distribution_ms_ * 1000 )
2224 , iterator_exhausted(false )
2325{
2426}
@@ -27,6 +29,8 @@ ObjectInfoPtr StorageObjectStorageStableTaskDistributor::getNextTask(size_t numb
2729{
2830 LOG_TRACE (log, " Received request from replica {} looking for a file" , number_of_current_replica);
2931
32+ saveLastNodeActivity (number_of_current_replica);
33+
3034 // 1. Check pre-queued files first
3135 if (auto file = getPreQueuedFile (number_of_current_replica))
3236 return file;
@@ -159,7 +163,7 @@ ObjectInfoPtr StorageObjectStorageStableTaskDistributor::getMatchingFileFromIter
159163 // Queue file for its assigned replica
160164 {
161165 std::lock_guard lock (mutex);
162- unprocessed_files.emplace (file_path, object_info);
166+ unprocessed_files.emplace (file_path, std::make_pair ( object_info, number_of_current_replica) );
163167 connection_to_files[file_replica_idx].push_back (object_info);
164168 }
165169 }
@@ -169,26 +173,65 @@ ObjectInfoPtr StorageObjectStorageStableTaskDistributor::getMatchingFileFromIter
169173
170174ObjectInfoPtr StorageObjectStorageStableTaskDistributor::getAnyUnprocessedFile (size_t number_of_current_replica)
171175{
176+ // / Limit time of node activity to keep task in queue
177+ Poco::Timestamp activity_limit;
178+ Poco::Timestamp oldest_activity;
179+ if (lock_object_storage_task_distribution_us > 0 )
180+ activity_limit -= lock_object_storage_task_distribution_us;
181+
172182 std::lock_guard lock (mutex);
173183
174184 if (!unprocessed_files.empty ())
175185 {
176186 auto it = unprocessed_files.begin ();
177- auto next_file = it->second ;
178- unprocessed_files.erase (it);
179187
180- auto file_path = send_over_whole_archive ? next_file->getPathOrPathToArchiveIfArchive () : next_file->getPath ();
188+ while (it != unprocessed_files.end ())
189+ {
190+ auto last_activity = last_node_activity.find (it->second .second );
191+ if (lock_object_storage_task_distribution_us <= 0
192+ || last_activity == last_node_activity.end ()
193+ || activity_limit > last_activity->second )
194+ {
195+ auto next_file = it->second .first ;
196+ unprocessed_files.erase (it);
197+
198+ auto file_path = send_over_whole_archive ? next_file->getPathOrPathToArchiveIfArchive () : next_file->getPath ();
199+ LOG_TRACE (
200+ log,
201+ " Iterator exhausted. Assigning unprocessed file {} to replica {}" ,
202+ file_path,
203+ number_of_current_replica
204+ );
205+
206+ return next_file;
207+ }
208+
209+ oldest_activity = std::min (oldest_activity, last_activity->second );
210+ ++it;
211+ }
212+
181213 LOG_TRACE (
182214 log,
183- " Iterator exhausted. Assigning unprocessed file {} to replica {} " ,
184- file_path ,
185- number_of_current_replica
215+ " No unprocessed file for replica {}, need to retry after {} us " ,
216+ number_of_current_replica ,
217+ oldest_activity - activity_limit
186218 );
187219
188- return next_file;
220+ // / All unprocessed files owned by alive replicas with recenlty activity
221+ // / Need to retry after (oldest_activity - activity_limit) microseconds
222+ RelativePathWithMetadata::CommandInTaskResponse response;
223+ response.set_retry_after_us (oldest_activity - activity_limit);
224+ return std::make_shared<ObjectInfo>(response.to_string ());
189225 }
190226
191227 return {};
192228}
193229
230+ void StorageObjectStorageStableTaskDistributor::saveLastNodeActivity (size_t number_of_current_replica)
231+ {
232+ Poco::Timestamp now;
233+ std::lock_guard lock (mutex);
234+ last_node_activity[number_of_current_replica] = now;
235+ }
236+
194237}
0 commit comments