From 817c5cec255df4e509c84f0ab59d752d6790a8b8 Mon Sep 17 00:00:00 2001 From: Vladimir Chebotarev Date: Tue, 13 Apr 2021 22:11:58 +0300 Subject: [PATCH] Correct S3 read retries. --- src/IO/ReadBufferFromS3.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/IO/ReadBufferFromS3.cpp b/src/IO/ReadBufferFromS3.cpp index f77a9dfb2be..07d1246b370 100644 --- a/src/IO/ReadBufferFromS3.cpp +++ b/src/IO/ReadBufferFromS3.cpp @@ -12,6 +12,7 @@ # include + namespace ProfileEvents { extern const Event S3ReadMicroseconds; @@ -40,9 +41,11 @@ ReadBufferFromS3::ReadBufferFromS3( { } - bool ReadBufferFromS3::nextImpl() { + /// Restoring valid value of `count()` during `nextImpl()`. See `ReadBuffer::next()`. + pos = working_buffer.begin(); + if (!impl) impl = initialize(); @@ -57,6 +60,10 @@ bool ReadBufferFromS3::nextImpl() try { next_result = impl->next(); + /// FIXME. 1. Poco `istream` cannot read less than buffer_size or this state is being discarded during + /// istream <-> iostream conversion. `gcount` always contains 0, + /// that's why we always have error "Cannot read from istream at offset 0". + break; } catch (const Exception & e) @@ -67,7 +74,6 @@ bool ReadBufferFromS3::nextImpl() bucket, key, getPosition(), attempt, e.message()); impl.reset(); - offset = getPosition(); if (!attempt) throw; @@ -102,7 +108,6 @@ off_t ReadBufferFromS3::seek(off_t offset_, int whence) return offset; } - off_t ReadBufferFromS3::getPosition() { return offset + count(); @@ -110,13 +115,13 @@ off_t ReadBufferFromS3::getPosition() std::unique_ptr ReadBufferFromS3::initialize() { - LOG_TRACE(log, "Read S3 object. Bucket: {}, Key: {}, Offset: {}", bucket, key, std::to_string(offset)); + LOG_TRACE(log, "Read S3 object. Bucket: {}, Key: {}, Offset: {}", bucket, key, getPosition()); Aws::S3::Model::GetObjectRequest req; req.SetBucket(bucket); req.SetKey(key); - if (offset != 0) - req.SetRange("bytes=" + std::to_string(offset) + "-"); + if (getPosition()) + req.SetRange("bytes=" + std::to_string(getPosition()) + "-"); Aws::S3::Model::GetObjectOutcome outcome = client_ptr->GetObject(req);