Skip to content

Commit c8ec2f1

Browse files
Robert Roeserfacebook-github-bot
Robert Roeser
authored andcommitted
abandon write
Summary: Lets you bail from writing to cursor without causing an exception. Useful when you have an error and don't want to continue writing. Reviewed By: yfeldblum Differential Revision: D71008395 fbshipit-source-id: 0fa60d87a3e8694c8e3be1b7f742b226e20a8836
1 parent 96add10 commit c8ec2f1

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

thrift/lib/cpp2/protocol/CursorBasedSerializer.h

+12
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,18 @@ class CursorSerializationWrapper {
186186
done();
187187
}
188188

189+
/**
190+
* Allows writing to be aborted. This is useful when you have an error
191+
* condition and you want to avoid writing to the buffer. Prevents
192+
* CursorSerializationWrapper dtor from throwing if the write was not
193+
* completed.
194+
*/
195+
void abandonWrite(StructuredCursorWriter<Tag>&& writer) {
196+
writer.abandon();
197+
queue_.reset();
198+
done();
199+
}
200+
189201
/** Access to serialized data */
190202
const folly::IOBuf& serializedData() const& {
191203
checkHasData();

thrift/lib/cpp2/protocol/detail/CursorBasedSerialization.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class BaseCursorWriter {
160160
Active,
161161
Child,
162162
Done,
163+
Abandonded,
163164
};
164165
State state_ = State::Active;
165166

@@ -183,7 +184,8 @@ class BaseCursorWriter {
183184
}
184185

185186
~BaseCursorWriter() {
186-
DCHECK(state_ == State::Done) << "Writer must be passed to endWrite";
187+
DCHECK(state_ == State::Done || state_ == State::Abandonded)
188+
<< "Writer must be passed to endWrite";
187189
}
188190

189191
BaseCursorWriter(BaseCursorWriter&& other) noexcept {
@@ -193,7 +195,8 @@ class BaseCursorWriter {
193195
}
194196
BaseCursorWriter& operator=(BaseCursorWriter&& other) noexcept {
195197
if (this != &other) {
196-
DCHECK(state_ == State::Done) << "Writer must be passed to endWrite";
198+
DCHECK(state_ == State::Done || state_ == State::Abandonded)
199+
<< "Writer must be passed to endWrite";
197200
protocol_ = std::move(other.protocol_);
198201
state_ = other.state_;
199202
other.state_ = State::Done;
@@ -207,6 +210,8 @@ class BaseCursorWriter {
207210

208211
template <typename T>
209212
friend class StructuredCursorWriter;
213+
214+
void abandon() { state_ = State::Abandonded; }
210215
};
211216

212217
// std::swap isn't constexpr until C++20 so we need to reimplement :(

thrift/lib/cpp2/protocol/test/CursorBasedSerializerTest.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -765,3 +765,10 @@ TEST(CursorBasedSerializer, ConcurrentAccess) {
765765
EXPECT_THROW(wrapper.beginWrite(), std::runtime_error);
766766
wrapper.endRead(std::move(reader));
767767
}
768+
769+
TEST(CursorSerializer, AbandonedWrite) {
770+
CursorSerializationWrapper<Qualifiers> wrapper;
771+
auto writer = wrapper.beginWrite();
772+
writer.write<ident::opt>(3);
773+
wrapper.abandonWrite(std::move(writer));
774+
}

0 commit comments

Comments
 (0)