| 219 | } |
| 220 | |
| 221 | BackupFileInfos buildFileInfosForBackupEntries(const BackupEntries & backup_entries, const BackupPtr & base_backup, const ReadSettings & read_settings, ThreadPool & thread_pool, QueryStatusPtr process_list_element) |
| 222 | { |
| 223 | LoggerPtr log = getLogger("FileInfosFromBackupEntries"); |
| 224 | LOG_TRACE(log, "Building file infos for backup entries"); |
| 225 | auto timer = CurrentThread::getProfileEvents().timer(ProfileEvents::BackupPreparingFileInfosMicroseconds); |
| 226 | |
| 227 | BackupFileInfos infos; |
| 228 | infos.resize(backup_entries.size()); |
| 229 | |
| 230 | std::atomic_bool failed = false; |
| 231 | |
| 232 | ThreadPoolCallbackRunnerLocal<void> runner(thread_pool, ThreadName::BACKUP_WORKER); |
| 233 | for (size_t i = 0; i != backup_entries.size(); ++i) |
| 234 | { |
| 235 | if (failed) |
| 236 | break; |
| 237 | |
| 238 | /// Passing references here is fine. All the objects are created **before** runner so they will be destroyed after it in case |
| 239 | /// of an exception |
| 240 | runner.enqueueAndKeepTrack([&infos, &backup_entries, &read_settings, &base_backup, &process_list_element, i, log, &failed, current_component = Coordination::getCurrentComponent()]() |
| 241 | { |
| 242 | if (failed) |
| 243 | return; |
| 244 | |
| 245 | auto component_guard = Coordination::setCurrentComponent(current_component); |
| 246 | try |
| 247 | { |
| 248 | const auto & name = backup_entries[i].first; |
| 249 | const auto & entry = backup_entries[i].second; |
| 250 | |
| 251 | if (process_list_element) |
| 252 | process_list_element->checkTimeLimit(); |
| 253 | |
| 254 | infos[i] = buildFileInfoForBackupEntry(name, entry, base_backup, read_settings, log); |
| 255 | } |
| 256 | catch (...) |
| 257 | { |
| 258 | failed = true; |
| 259 | throw; |
| 260 | } |
| 261 | }); |
| 262 | } |
| 263 | |
| 264 | runner.waitForAllToFinishAndRethrowFirstError(); |
| 265 | |
| 266 | return infos; |
| 267 | } |
| 268 | |
| 269 | } |
no test coverage detected