kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From danburk...@apache.org
Subject [3/3] kudu git commit: util: add Status::AndThen combinator
Date Wed, 12 Jul 2017 18:27:08 GMT
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 <aserbin@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 <danburkert@apache.org>
Authored: Mon Jul 10 11:04:22 2017 -0700
Committer: Dan Burkert <danburkert@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.


Mime
View raw message