Skip to content

Commit 94da831

Browse files
committed
Safer IObjectStorage::tryGetObjectMetadata() (ignore only object existence error)
1 parent b3f9e63 commit 94da831

File tree

12 files changed

+71
-16
lines changed

12 files changed

+71
-16
lines changed

src/Disks/ObjectStorages/AzureBlobStorage/AzureObjectStorage.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,18 @@ ObjectMetadata AzureObjectStorage::getObjectMetadata(const std::string & path) c
325325
return result;
326326
}
327327

328+
std::optional<ObjectMetadata> AzureObjectStorage::tryGetObjectMetadata(const std::string & path) const
329+
try
330+
{
331+
return getObjectMetadata(path);
332+
}
333+
catch (const Azure::Storage::StorageException & e)
334+
{
335+
if (e.StatusCode == Azure::Core::Http::HttpStatusCode::NotFound)
336+
return {};
337+
throw;
338+
}
339+
328340
void AzureObjectStorage::copyObject( /// NOLINT
329341
const StoredObject & object_from,
330342
const StoredObject & object_to,

src/Disks/ObjectStorages/AzureBlobStorage/AzureObjectStorage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class AzureObjectStorage : public IObjectStorage
7474

7575
ObjectMetadata getObjectMetadata(const std::string & path) const override;
7676

77+
std::optional<ObjectMetadata> tryGetObjectMetadata(const std::string & path) const override;
78+
7779
ObjectStorageConnectionInfoPtr getConnectionInfo() const override;
7880

7981
void copyObject( /// NOLINT

src/Disks/ObjectStorages/Cached/CachedObjectStorage.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ ObjectMetadata CachedObjectStorage::getObjectMetadata(const std::string & path)
202202
return object_storage->getObjectMetadata(path);
203203
}
204204

205+
std::optional<ObjectMetadata> CachedObjectStorage::tryGetObjectMetadata(const std::string & path) const
206+
{
207+
return object_storage->tryGetObjectMetadata(path);
208+
}
209+
205210
void CachedObjectStorage::shutdown()
206211
{
207212
object_storage->shutdown();

src/Disks/ObjectStorages/Cached/CachedObjectStorage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class CachedObjectStorage final : public IObjectStorage
6767

6868
ObjectMetadata getObjectMetadata(const std::string & path) const override;
6969

70+
std::optional<ObjectMetadata> tryGetObjectMetadata(const std::string & path) const override;
71+
7072
ObjectStorageConnectionInfoPtr getConnectionInfo() const override { return object_storage->getConnectionInfo(); }
7173

7274
void shutdown() override;

src/Disks/ObjectStorages/HDFS/HDFSObjectStorage.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,26 @@ void HDFSObjectStorage::removeObjectsIfExist(const StoredObjects & objects)
151151
}
152152

153153
ObjectMetadata HDFSObjectStorage::getObjectMetadata(const std::string & path) const
154+
{
155+
auto metadata = tryGetObjectMetadata(path);
156+
if (!metadata.has_value())
157+
throw Exception(ErrorCodes::HDFS_ERROR,
158+
"{} does not exist. Error: {}", path, hdfsGetLastError());
159+
return metadata.value();
160+
}
161+
162+
std::optional<ObjectMetadata> HDFSObjectStorage::tryGetObjectMetadata(const std::string & path) const
154163
{
155164
initializeHDFSFS();
156165
auto * file_info = wrapErr<hdfsFileInfo *>(hdfsGetPathInfo, hdfs_fs.get(), path.data());
157166
if (!file_info)
167+
{
168+
if (errno == ENOENT)
169+
return {};
170+
158171
throw Exception(ErrorCodes::HDFS_ERROR,
159172
"Cannot get file info for: {}. Error: {}", path, hdfsGetLastError());
173+
}
160174

161175
ObjectMetadata metadata;
162176
metadata.size_bytes = static_cast<size_t>(file_info->mSize);

src/Disks/ObjectStorages/HDFS/HDFSObjectStorage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class HDFSObjectStorage : public IObjectStorage, public HDFSErrorWrapper
8484

8585
ObjectMetadata getObjectMetadata(const std::string & path) const override;
8686

87+
std::optional<ObjectMetadata> tryGetObjectMetadata(const std::string & path) const override;
88+
8789
void copyObject( /// NOLINT
8890
const StoredObject & object_from,
8991
const StoredObject & object_to,

src/Disks/ObjectStorages/IObjectStorage.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,6 @@ ObjectStorageIteratorPtr IObjectStorage::iterate(const std::string & path_prefix
4444
return std::make_shared<ObjectStorageIteratorFromList>(std::move(files));
4545
}
4646

47-
std::optional<ObjectMetadata> IObjectStorage::tryGetObjectMetadata(const std::string & path) const
48-
{
49-
try
50-
{
51-
return getObjectMetadata(path);
52-
}
53-
catch (...)
54-
{
55-
return {};
56-
}
57-
}
58-
5947
ThreadPool & IObjectStorage::getThreadPoolWriter()
6048
{
6149
auto context = Context::getGlobalContextInstance();

src/Disks/ObjectStorages/IObjectStorage.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,13 @@ class IObjectStorage
197197
/// List objects recursively by certain prefix. Use it instead of listObjects, if you want to list objects lazily.
198198
virtual ObjectStorageIteratorPtr iterate(const std::string & path_prefix, size_t max_keys) const;
199199

200-
/// Get object metadata if supported. It should be possible to receive
201-
/// at least size of object
202-
virtual std::optional<ObjectMetadata> tryGetObjectMetadata(const std::string & path) const;
203-
204200
/// Get object metadata if supported. It should be possible to receive
205201
/// at least size of object
206202
virtual ObjectMetadata getObjectMetadata(const std::string & path) const = 0;
207203

204+
/// Same as getObjectMetadata(), but ignores if object does not exist.
205+
virtual std::optional<ObjectMetadata> tryGetObjectMetadata(const std::string & path) const = 0;
206+
208207
virtual ObjectStorageConnectionInfoPtr getConnectionInfo() const { return nullptr; }
209208

210209
/// Read single object

src/Disks/ObjectStorages/Local/LocalObjectStorage.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,29 @@ ObjectMetadata LocalObjectStorage::getObjectMetadata(const std::string & path) c
148148
return object_metadata;
149149
}
150150

151+
std::optional<ObjectMetadata> LocalObjectStorage::tryGetObjectMetadata(const std::string & path) const
152+
{
153+
ObjectMetadata object_metadata;
154+
LOG_TEST(log, "Getting metadata for path: {}", path);
155+
156+
std::error_code error;
157+
auto time = fs::last_write_time(path, error);
158+
if (error)
159+
{
160+
if (error == std::errc::no_such_file_or_directory)
161+
return {};
162+
throw fs::filesystem_error("Got unexpected error while getting last write time", path, error);
163+
}
164+
165+
/// no_such_file_or_directory is ignored only for last_write_time for consistency
166+
object_metadata.size_bytes = fs::file_size(path);
167+
168+
object_metadata.etag = std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(time.time_since_epoch()).count());
169+
object_metadata.last_modified = Poco::Timestamp::fromEpochTime(
170+
std::chrono::duration_cast<std::chrono::seconds>(time.time_since_epoch()).count());
171+
return object_metadata;
172+
}
173+
151174
void LocalObjectStorage::listObjects(const std::string & path, RelativePathsWithMetadata & children, size_t/* max_keys */) const
152175
{
153176
if (!fs::exists(path) || !fs::is_directory(path))

src/Disks/ObjectStorages/Local/LocalObjectStorage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class LocalObjectStorage : public IObjectStorage
6161

6262
ObjectMetadata getObjectMetadata(const std::string & path) const override;
6363

64+
std::optional<ObjectMetadata> tryGetObjectMetadata(const std::string & path) const override;
65+
6466
void listObjects(const std::string & path, RelativePathsWithMetadata & children, size_t max_keys) const override;
6567

6668
bool existsOrHasAnyChild(const std::string & path) const override;

0 commit comments

Comments
 (0)