You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by mp...@apache.org on 2016/07/14 06:13:29 UTC

[1/2] incubator-kudu git commit: Add information about Exactly Once RPC semantics to rpc.md

Repository: incubator-kudu
Updated Branches:
  refs/heads/master 3c01d4c05 -> 1a1d3a8d2


Add information about Exactly Once RPC semantics to rpc.md

This patch adds some info about exactly one rpc semantics to
rpc.md, mostly from a usage perspective.

Change-Id: I8acf4e830eb673b6a696b12188bb9aafb65b261e
Reviewed-on: http://gerrit.cloudera.org:8080/3503
Tested-by: Kudu Jenkins
Reviewed-by: Todd Lipcon <to...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kudu/commit/374527a8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kudu/tree/374527a8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kudu/diff/374527a8

Branch: refs/heads/master
Commit: 374527a83f17a420ea337e99b6a99c40efd95dce
Parents: 3c01d4c
Author: David Alves <da...@cloudera.com>
Authored: Sun Jun 26 18:27:13 2016 -0700
Committer: Todd Lipcon <to...@apache.org>
Committed: Wed Jul 13 04:13:03 2016 +0000

----------------------------------------------------------------------
 docs/design-docs/rpc.md | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/374527a8/docs/design-docs/rpc.md
----------------------------------------------------------------------
diff --git a/docs/design-docs/rpc.md b/docs/design-docs/rpc.md
index bddbbfd..5c3608f 100644
--- a/docs/design-docs/rpc.md
+++ b/docs/design-docs/rpc.md
@@ -166,6 +166,34 @@ There is a ServicePool which you can use to coordinate several worker threads
 handling callbacks.
 
 -------------------------------------------------------------------------------
+Exactly once semantics
+-------------------------------------------------------------------------------
+Exactly once semantics can be enabled for RPCs that require them by using
+the 'track_rpc_result' option when declaring a service interface method.
+
+Example:
+```
+service CalculatorService {
+  rpc AddExactlyOnce(ExactlyOnceRequestPB) returns (ExactlyOnceResponsePB) {
+    option (kudu.track_rpc_result) = true;
+  }
+}
+```
+
+This works in tandem with unique identifier for an RPC (RequestIdPB, see
+rpc_header.proto) that must be specified on the RPC header.
+
+When both the option was selected and the unique identifier is available
+the server will make sure that, independently of how many retries, an RPC
+with a certain id is executed exactly once and that all retries receive
+the same response.
+
+Note that enabling the option only guarantees exactly once semantics for
+the lifetime of the server, making sure that responses survive crashes
+and are also available in replicas (for replicated RPCs, like writes) needs
+that actions be taken outside of the RPC subsystem.
+
+-------------------------------------------------------------------------------
 RPC Sidecars
 -------------------------------------------------------------------------------
 RPC sidecars are used to avoid excess copies for large volumes of data.


[2/2] incubator-kudu git commit: Make RequestTracker not return Status on FirstIncomplete()

Posted by mp...@apache.org.
Make RequestTracker not return Status on FirstIncomplete()

This addresses Todd's post-commit comment on the fact that RequestTracker::FirstIncomplete()
shouldn't return a Status and should return NO_SEQ_NO instead.

Change-Id: I0cdcb2b4c0d2d983bd684b5dccf75a81530da93e
Reviewed-on: http://gerrit.cloudera.org:8080/3504
Tested-by: Kudu Jenkins
Reviewed-by: Todd Lipcon <to...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-kudu/commit/1a1d3a8d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-kudu/tree/1a1d3a8d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-kudu/diff/1a1d3a8d

Branch: refs/heads/master
Commit: 1a1d3a8d2353766bacff17e745554c61ed1d3286
Parents: 374527a
Author: David Alves <da...@cloudera.com>
Authored: Mon Jun 27 01:56:49 2016 -0700
Committer: David Ribeiro Alves <dr...@apache.org>
Committed: Wed Jul 13 05:15:41 2016 +0000

----------------------------------------------------------------------
 src/kudu/rpc/request_tracker-test.cc | 22 ++++++++--------------
 src/kudu/rpc/request_tracker.cc      |  9 +++++----
 src/kudu/rpc/request_tracker.h       |  5 +++--
 3 files changed, 16 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/1a1d3a8d/src/kudu/rpc/request_tracker-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/rpc/request_tracker-test.cc b/src/kudu/rpc/request_tracker-test.cc
index 19efef6..89ea8a2 100644
--- a/src/kudu/rpc/request_tracker-test.cc
+++ b/src/kudu/rpc/request_tracker-test.cc
@@ -32,32 +32,28 @@ TEST(RequestTrackerTest, TestSequenceNumberGeneration) {
   scoped_refptr<RequestTracker> tracker_(new RequestTracker("test_client"));
 
   // A new tracker should have no incomplete RPCs
-  ASSERT_TRUE(tracker_->FirstIncomplete(nullptr).IsNotFound());
+  RequestTracker::SequenceNumber seq_no = tracker_->FirstIncomplete();
+  ASSERT_EQ(seq_no, RequestTracker::NO_SEQ_NO);
 
   vector<RequestTracker::SequenceNumber> generated_seq_nos;
 
   // Generate MAX in flight RPCs, making sure they are correctly returned.
   for (int i = 0; i < MAX; i++) {
-    RequestTracker::SequenceNumber seq_no;
     ASSERT_OK(tracker_->NewSeqNo(&seq_no));
     generated_seq_nos.push_back(seq_no);
   }
 
   // Now we should get a first incomplete.
-  RequestTracker::SequenceNumber first_incomplete;
-  ASSERT_OK(tracker_->FirstIncomplete(&first_incomplete));
-  ASSERT_EQ(generated_seq_nos[0], first_incomplete);
+  ASSERT_EQ(generated_seq_nos[0], tracker_->FirstIncomplete());
 
   // Marking 'first_incomplete' as done, should advance the first incomplete.
-  tracker_->RpcCompleted(first_incomplete);
+  tracker_->RpcCompleted(tracker_->FirstIncomplete());
 
-  ASSERT_OK(tracker_->FirstIncomplete(&first_incomplete));
-  ASSERT_EQ(generated_seq_nos[1], first_incomplete);
+  ASSERT_EQ(generated_seq_nos[1], tracker_->FirstIncomplete());
 
   // Marking a 'middle' rpc, should not advance 'first_incomplete'.
   tracker_->RpcCompleted(generated_seq_nos[5]);
-  ASSERT_OK(tracker_->FirstIncomplete(&first_incomplete));
-  ASSERT_EQ(generated_seq_nos[1], first_incomplete);
+  ASSERT_EQ(generated_seq_nos[1], tracker_->FirstIncomplete());
 
   // Marking half the rpc as complete should advance FirstIncomplete.
   // Note that this also tests that RequestTracker::RpcCompleted() is idempotent, i.e. that
@@ -66,11 +62,9 @@ TEST(RequestTrackerTest, TestSequenceNumberGeneration) {
     tracker_->RpcCompleted(generated_seq_nos[i]);
   }
 
-  ASSERT_OK(tracker_->FirstIncomplete(&first_incomplete));
-  ASSERT_EQ(generated_seq_nos[6], first_incomplete);
+  ASSERT_EQ(generated_seq_nos[6], tracker_->FirstIncomplete());
 
   for (int i = MAX / 2; i <= MAX; i++) {
-    RequestTracker::SequenceNumber seq_no;
     ASSERT_OK(tracker_->NewSeqNo(&seq_no));
     generated_seq_nos.push_back(seq_no);
   }
@@ -81,7 +75,7 @@ TEST(RequestTrackerTest, TestSequenceNumberGeneration) {
     tracker_->RpcCompleted(seq_no);
   }
 
-  ASSERT_TRUE(tracker_->FirstIncomplete(nullptr).IsNotFound());
+  ASSERT_EQ(tracker_->FirstIncomplete(), RequestTracker::NO_SEQ_NO);
 }
 
 } // namespace rpc

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/1a1d3a8d/src/kudu/rpc/request_tracker.cc
----------------------------------------------------------------------
diff --git a/src/kudu/rpc/request_tracker.cc b/src/kudu/rpc/request_tracker.cc
index 79e4578..1958664 100644
--- a/src/kudu/rpc/request_tracker.cc
+++ b/src/kudu/rpc/request_tracker.cc
@@ -24,6 +24,8 @@
 namespace kudu {
 namespace rpc {
 
+const RequestTracker::SequenceNumber RequestTracker::NO_SEQ_NO = -1;
+
 RequestTracker::RequestTracker(const string& client_id)
     : client_id_(client_id),
       next_(0) {}
@@ -36,11 +38,10 @@ Status RequestTracker::NewSeqNo(SequenceNumber* seq_no) {
   return Status::OK();
 }
 
-Status RequestTracker::FirstIncomplete(SequenceNumber* seq_no) {
+RequestTracker::SequenceNumber RequestTracker::FirstIncomplete() {
   std::lock_guard<simple_spinlock> l(lock_);
-  if (incomplete_rpcs_.empty()) return Status::NotFound("There are no incomplete RPCs");
-  *seq_no = *incomplete_rpcs_.begin();
-  return Status::OK();
+  if (incomplete_rpcs_.empty()) return NO_SEQ_NO;
+  return *incomplete_rpcs_.begin();
 }
 
 void RequestTracker::RpcCompleted(const SequenceNumber& seq_no) {

http://git-wip-us.apache.org/repos/asf/incubator-kudu/blob/1a1d3a8d/src/kudu/rpc/request_tracker.h
----------------------------------------------------------------------
diff --git a/src/kudu/rpc/request_tracker.h b/src/kudu/rpc/request_tracker.h
index 8147e21..99f8d6c 100644
--- a/src/kudu/rpc/request_tracker.h
+++ b/src/kudu/rpc/request_tracker.h
@@ -48,6 +48,7 @@ namespace rpc {
 class RequestTracker : public RefCountedThreadSafe<RequestTracker> {
  public:
   typedef int64_t SequenceNumber;
+  static const RequestTracker::SequenceNumber NO_SEQ_NO;
   explicit RequestTracker(const std::string& client_id);
 
   // Creates a new, unique, sequence number.
@@ -58,8 +59,8 @@ class RequestTracker : public RefCountedThreadSafe<RequestTracker> {
   Status NewSeqNo(SequenceNumber* seq_no);
 
   // Returns the sequence number of the first incomplete RPC.
-  // If there is no incomplete RPC returns Status::NotFound. 'seq_no' is not set.
-  Status FirstIncomplete(SequenceNumber* seq_no);
+  // If there is no incomplete RPC returns NO_SEQ_NO.
+  SequenceNumber FirstIncomplete();
 
   // Marks the rpc with 'seq_no' as completed.
   void RpcCompleted(const SequenceNumber& seq_no);