| 105 | } |
| 106 | |
| 107 | std::unique_ptr<ReadBufferFromFileBase> |
| 108 | DiskCacheWrapper::readFile( |
| 109 | const String & path, |
| 110 | const ReadSettings& settings) const |
| 111 | { |
| 112 | if (!cache_file_predicate(path)) |
| 113 | return DiskDecorator::readFile(path, settings); |
| 114 | |
| 115 | LOG_DEBUG(log, "Read file {} from cache", backQuote(path)); |
| 116 | |
| 117 | if (cache_disk->exists(path)) |
| 118 | return cache_disk->readFile(path, settings); |
| 119 | |
| 120 | auto metadata = acquireDownloadMetadata(path); |
| 121 | |
| 122 | { |
| 123 | std::unique_lock<std::mutex> lock{mutex}; |
| 124 | |
| 125 | if (metadata->status == NONE) |
| 126 | { |
| 127 | /// This thread will responsible for file downloading to cache. |
| 128 | metadata->status = DOWNLOADING; |
| 129 | LOG_DEBUG(log, "File {} doesn't exist in cache. Will download it", backQuote(path)); |
| 130 | } |
| 131 | else if (metadata->status == DOWNLOADING) |
| 132 | { |
| 133 | LOG_DEBUG(log, "Waiting for file {} download to cache", backQuote(path)); |
| 134 | metadata->condition.wait(lock, [metadata] { return metadata->status == DOWNLOADED || metadata->status == ERROR; }); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | if (metadata->status == DOWNLOADING) |
| 139 | { |
| 140 | FileDownloadStatus result_status = DOWNLOADED; |
| 141 | |
| 142 | if (!cache_disk->exists(path)) |
| 143 | { |
| 144 | try |
| 145 | { |
| 146 | auto dir_path = directoryPath(path); |
| 147 | if (!cache_disk->exists(dir_path)) |
| 148 | cache_disk->createDirectories(dir_path); |
| 149 | |
| 150 | auto tmp_path = path + ".tmp"; |
| 151 | { |
| 152 | auto src_buffer = DiskDecorator::readFile(path, settings); |
| 153 | auto dst_buffer = cache_disk->writeFile(tmp_path, {.buffer_size = settings.local_fs_buffer_size, .mode = WriteMode::Rewrite}); |
| 154 | copyData(*src_buffer, *dst_buffer); |
| 155 | } |
| 156 | cache_disk->moveFile(tmp_path, path); |
| 157 | |
| 158 | LOG_DEBUG(log, "File {} downloaded to cache", backQuote(path)); |
| 159 | } |
| 160 | catch (...) |
| 161 | { |
| 162 | tryLogCurrentException("DiskCache", "Failed to download file + " + backQuote(path) + " to cache"); |
| 163 | result_status = ERROR; |
| 164 | } |
no test coverage detected