diff --git a/src/IO/WriteBuffer.cpp b/src/IO/WriteBuffer.cpp index dfcf8432afb..2ed14222ffc 100644 --- a/src/IO/WriteBuffer.cpp +++ b/src/IO/WriteBuffer.cpp @@ -20,7 +20,7 @@ WriteBuffer::~WriteBuffer() LoggerPtr log = getLogger("WriteBuffer"); LOG_ERROR( log, - "WriteBuffer is not finalized when destructor is called. " + "WriteBuffer is neither finalized nor canceled when destructor is called. " "No exceptions in flight are detected. " "The file might not be written at all or might be truncated. " "Stack trace: {}", diff --git a/src/IO/WriteBuffer.h b/src/IO/WriteBuffer.h index 7a9046ded5d..8b429891567 100644 --- a/src/IO/WriteBuffer.h +++ b/src/IO/WriteBuffer.h @@ -59,6 +59,9 @@ public: */ pos = working_buffer.begin(); bytes += bytes_in_buffer; + + cancel(); + throw; } @@ -133,28 +136,21 @@ public: catch (...) { pos = working_buffer.begin(); - finalized = true; + + cancel(); + throw; } } - void cancel() + void cancel() noexcept { if (canceled || finalized) return; LockMemoryExceptionInThread lock(VariableContext::Global); - try - { - cancelImpl(); - canceled = true; - } - catch (...) - { - pos = working_buffer.begin(); - canceled = true; - throw; - } + cancelImpl(); + canceled = true; } /// Wait for data to be reliably written. Mainly, call fsync for fd. @@ -172,7 +168,7 @@ protected: next(); } - virtual void cancelImpl() + virtual void cancelImpl() noexcept { } diff --git a/src/IO/WriteBufferDecorator.h b/src/IO/WriteBufferDecorator.h index 77f11424482..109c2bd24e4 100644 --- a/src/IO/WriteBufferDecorator.h +++ b/src/IO/WriteBufferDecorator.h @@ -47,7 +47,7 @@ public: } } - void cancelImpl() override + void cancelImpl() noexcept override { out->cancel(); } diff --git a/src/IO/WriteBufferFromFileDecorator.cpp b/src/IO/WriteBufferFromFileDecorator.cpp index 0e4e5e13a86..b1e7d843d92 100644 --- a/src/IO/WriteBufferFromFileDecorator.cpp +++ b/src/IO/WriteBufferFromFileDecorator.cpp @@ -28,6 +28,12 @@ void WriteBufferFromFileDecorator::finalizeImpl() } } +void WriteBufferFromFileDecorator::cancelImpl() noexcept +{ + SwapHelper swap(*this, *impl); + impl->cancel(); +} + WriteBufferFromFileDecorator::~WriteBufferFromFileDecorator() { /// It is not a mistake that swap is called here diff --git a/src/IO/WriteBufferFromFileDecorator.h b/src/IO/WriteBufferFromFileDecorator.h index 5344bb1425c..07f843986bb 100644 --- a/src/IO/WriteBufferFromFileDecorator.h +++ b/src/IO/WriteBufferFromFileDecorator.h @@ -24,6 +24,8 @@ public: protected: void finalizeImpl() override; + void cancelImpl() noexcept override; + std::unique_ptr impl; private: diff --git a/src/IO/WriteBufferFromS3.cpp b/src/IO/WriteBufferFromS3.cpp index bc7792ff138..7ac16c4c76b 100644 --- a/src/IO/WriteBufferFromS3.cpp +++ b/src/IO/WriteBufferFromS3.cpp @@ -224,7 +224,7 @@ void WriteBufferFromS3::finalizeImpl() } } -void WriteBufferFromS3::cancelImpl() +void WriteBufferFromS3::cancelImpl() noexcept { tryToAbortMultipartUpload(); } @@ -251,7 +251,7 @@ String WriteBufferFromS3::getShortLogDetails() const bucket, key, multipart_upload_details); } -void WriteBufferFromS3::tryToAbortMultipartUpload() +void WriteBufferFromS3::tryToAbortMultipartUpload() noexcept { try { diff --git a/src/IO/WriteBufferFromS3.h b/src/IO/WriteBufferFromS3.h index 5f06a44e5f0..b026da607c5 100644 --- a/src/IO/WriteBufferFromS3.h +++ b/src/IO/WriteBufferFromS3.h @@ -54,7 +54,7 @@ private: /// Receives response from the server after sending all data. void finalizeImpl() override; - void cancelImpl() override; + void cancelImpl() noexcept override; String getVerboseLogDetails() const; String getShortLogDetails() const; @@ -73,7 +73,7 @@ private: void createMultipartUpload(); void completeMultipartUpload(); void abortMultipartUpload(); - void tryToAbortMultipartUpload(); + void tryToAbortMultipartUpload() noexcept; S3::PutObjectRequest getPutRequest(PartData & data); void makeSinglepartUpload(PartData && data);