You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by da...@apache.org on 2017/07/12 18:27:08 UTC
[3/3] kudu git commit: util: add Status::AndThen combinator
util: add Status::AndThen combinator
The AndThen combinator makes it easier to chain together
Status-returning operations when failure recovery is something other
than returning early. RETURN_NOT_OK already handles the return-early
case elegantly.
Also tweaks Status::CloneAndPrepend and Status::CloneAndAppend to be
usable with OK status values.
Change-Id: Ia6e1a79ff95406825d4238a8157d242252562805
Reviewed-on: http://gerrit.cloudera.org:8080/7399
Tested-by: Kudu Jenkins
Reviewed-by: Alexey Serbin <as...@cloudera.com>
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/69ee17dc
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/69ee17dc
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/69ee17dc
Branch: refs/heads/master
Commit: 69ee17dc795cab630e67d686cc66276547cc3ebd
Parents: 96cdcbd
Author: Dan Burkert <da...@apache.org>
Authored: Mon Jul 10 11:04:22 2017 -0700
Committer: Dan Burkert <da...@apache.org>
Committed: Wed Jul 12 18:26:39 2017 +0000
----------------------------------------------------------------------
src/kudu/util/status-test.cc | 19 +++++++++++++++++++
src/kudu/util/status.cc | 6 ++++++
src/kudu/util/status.h | 37 +++++++++++++++++++++++++++++++++++--
3 files changed, 60 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/69ee17dc/src/kudu/util/status-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/status-test.cc b/src/kudu/util/status-test.cc
index d5aa130..1ff8182 100644
--- a/src/kudu/util/status-test.cc
+++ b/src/kudu/util/status-test.cc
@@ -94,5 +94,24 @@ TEST(StatusTest, TestMoveAssignment) {
}
}
+TEST(StatusTest, TestAndThen) {
+ ASSERT_OK(Status::OK().AndThen(Status::OK)
+ .AndThen(Status::OK)
+ .AndThen(Status::OK));
+
+ ASSERT_TRUE(Status::InvalidArgument("").AndThen([] { return Status::IllegalState(""); })
+ .IsInvalidArgument());
+ ASSERT_TRUE(Status::InvalidArgument("").AndThen(Status::OK)
+ .IsInvalidArgument());
+ ASSERT_TRUE(Status::OK().AndThen([] { return Status::InvalidArgument(""); })
+ .AndThen(Status::OK)
+ .IsInvalidArgument());
+
+ ASSERT_EQ("foo: bar",
+ Status::OK().CloneAndPrepend("baz")
+ .AndThen([] {
+ return Status::InvalidArgument("bar").CloneAndPrepend("foo");
+ }).message());
+}
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/69ee17dc/src/kudu/util/status.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/status.cc b/src/kudu/util/status.cc
index 9f88da1..2d368dd 100644
--- a/src/kudu/util/status.cc
+++ b/src/kudu/util/status.cc
@@ -145,10 +145,16 @@ int16_t Status::posix_code() const {
}
Status Status::CloneAndPrepend(const Slice& msg) const {
+ if (ok()) {
+ return *this;
+ }
return Status(code(), msg, message(), posix_code());
}
Status Status::CloneAndAppend(const Slice& msg) const {
+ if (ok()) {
+ return *this;
+ }
return Status(code(), message(), msg, posix_code());
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/69ee17dc/src/kudu/util/status.h
----------------------------------------------------------------------
diff --git a/src/kudu/util/status.h b/src/kudu/util/status.h
index 93a25a6..5028392 100644
--- a/src/kudu/util/status.h
+++ b/src/kudu/util/status.h
@@ -160,6 +160,35 @@ class KUDU_EXPORT Status {
/// rvalue reference to a Status object.
/// @return The reference to the modified object.
Status& operator=(Status&& s);
+
+ /// If this status is OK, calls 'op' and returns the result, otherwise returns
+ /// this status.
+ ///
+ /// This method can be used to chain together multiple Status-returning
+ /// operations, short circuiting after the first one to fail.
+ ///
+ /// Example:
+ ///
+ /// @code
+ /// unique_ptr<SequentialFile> file;
+ /// Status s = Env::Default()
+ /// ->NewSequentialFile("/tmp/example.txt", &file)
+ /// .AndThen([&] {
+ /// return file->Write(0, "some data")
+ /// .CloneAndPrepend("failed to write to example file");
+ /// });
+ /// @endcode
+ ///
+ /// @param [in] op
+ /// Status-returning closure or function to run.
+ /// @return 'this', if this is not OK, or the result of running op.
+ template<typename F>
+ Status AndThen(F op) {
+ if (ok()) {
+ return op();
+ }
+ return *this;
+ }
#endif
/// @return A success status.
@@ -330,7 +359,9 @@ class KUDU_EXPORT Status {
/// or @c -1 if there is none.
int16_t posix_code() const;
- /// Clone the object and add the specified prefix to the clone's message.
+ /// Clone this status and add the specified prefix to the message.
+ ///
+ /// If this status is OK, then an OK status will be returned.
///
/// @param [in] msg
/// The message to prepend.
@@ -338,7 +369,9 @@ class KUDU_EXPORT Status {
/// leading message.
Status CloneAndPrepend(const Slice& msg) const;
- /// Clone the object and add the specified suffix to the clone's message.
+ /// Clone this status and add the specified suffix to the message.
+ ///
+ /// If this status is OK, then an OK status will be returned.
///
/// @param [in] msg
/// The message to append.