aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar yangg <yangg@google.com>2015-01-06 10:16:15 -0800
committerGravatar Nicolas Noble <nnoble@google.com>2015-01-06 17:45:46 -0800
commited5e7e006b1a60ef01a0ee1db144e959436b53d7 (patch)
tree4166d8504d804d00ff96e8ce47ae4e6ecf7e2152
parentc87b1c533f84a9bed94143908b00b0cc498cfda5 (diff)
Add deadline API on server side.
Change on 2015/01/06 by yangg <yangg@google.com> ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=83351442
-rw-r--r--include/grpc++/server_context.h4
-rw-r--r--src/cpp/server/server_context_impl.cc2
-rw-r--r--src/cpp/server/server_context_impl.h14
-rw-r--r--src/cpp/server/server_rpc_handler.cc2
-rw-r--r--src/cpp/util/time.cc3
-rw-r--r--test/cpp/end2end/end2end_test.cc93
-rw-r--r--test/cpp/util/echo.proto13
-rw-r--r--test/cpp/util/time_test.cc6
8 files changed, 129 insertions, 8 deletions
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index 9a14faa7fa..47fd6cf1c8 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -34,12 +34,16 @@
#ifndef __GRPCPP_SERVER_CONTEXT_H_
#define __GRPCPP_SERVER_CONTEXT_H_
+#include <chrono>
+
namespace grpc {
// Interface of server side rpc context.
class ServerContext {
public:
virtual ~ServerContext() {}
+
+ virtual std::chrono::system_clock::time_point absolute_deadline() const = 0;
};
} // namespace grpc
diff --git a/src/cpp/server/server_context_impl.cc b/src/cpp/server/server_context_impl.cc
index a229fcb6c9..13f2a3ae1a 100644
--- a/src/cpp/server/server_context_impl.cc
+++ b/src/cpp/server/server_context_impl.cc
@@ -35,6 +35,4 @@
namespace grpc {
-ServerContextImpl::ServerContextImpl() {}
-
} // namespace grpc
diff --git a/src/cpp/server/server_context_impl.h b/src/cpp/server/server_context_impl.h
index 58c4293b4f..c6016b7635 100644
--- a/src/cpp/server/server_context_impl.h
+++ b/src/cpp/server/server_context_impl.h
@@ -36,12 +36,24 @@
#include <grpc++/server_context.h>
+#include <chrono>
+
+#include <grpc/support/time.h>
+
namespace grpc {
class ServerContextImpl : public ServerContext {
public:
- ServerContextImpl();
+ explicit ServerContextImpl(std::chrono::system_clock::time_point deadline)
+ : absolute_deadline_(deadline) {}
~ServerContextImpl() {}
+
+ std::chrono::system_clock::time_point absolute_deadline() const {
+ return absolute_deadline_;
+ }
+
+ private:
+ std::chrono::system_clock::time_point absolute_deadline_;
};
} // namespace grpc
diff --git a/src/cpp/server/server_rpc_handler.cc b/src/cpp/server/server_rpc_handler.cc
index c32722f81a..3954f04f97 100644
--- a/src/cpp/server/server_rpc_handler.cc
+++ b/src/cpp/server/server_rpc_handler.cc
@@ -53,7 +53,7 @@ void ServerRpcHandler::StartRpc() {
return;
}
- ServerContextImpl user_context;
+ ServerContextImpl user_context(async_server_context_->absolute_deadline());
if (method_->method_type() == RpcMethod::NORMAL_RPC) {
// Start the rpc on this dedicated completion queue.
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc
index 6976fa1b32..e58dde82a3 100644
--- a/src/cpp/util/time.cc
+++ b/src/cpp/util/time.cc
@@ -53,6 +53,9 @@ void Timepoint2Timespec(const system_clock::time_point& from,
}
system_clock::time_point Timespec2Timepoint(gpr_timespec t) {
+ if (gpr_time_cmp(t, gpr_inf_future) == 0) {
+ return system_clock::time_point::max();
+ }
system_clock::time_point tp;
tp += duration_cast<system_clock::time_point::duration>(seconds(t.tv_sec));
tp +=
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 4b5a9a8e6a..83037b5ab1 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -31,10 +31,12 @@
*
*/
+#include <chrono>
#include <thread>
-#include "src/cpp/server/rpc_service_method.h"
+
#include "test/cpp/util/echo.pb.h"
-#include "net/util/netutil.h"
+#include "src/cpp/server/rpc_service_method.h"
+#include "src/cpp/util/time.h"
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
@@ -44,22 +46,43 @@
#include <grpc++/server_context.h>
#include <grpc++/status.h>
#include <grpc++/stream.h>
+#include "net/util/netutil.h"
#include <gtest/gtest.h>
#include <grpc/grpc.h>
#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
using grpc::cpp::test::util::EchoRequest;
using grpc::cpp::test::util::EchoResponse;
using grpc::cpp::test::util::TestService;
+using std::chrono::system_clock;
namespace grpc {
+namespace testing {
+
+namespace {
+
+// When echo_deadline is requested, deadline seen in the ServerContext is set in
+// the response in seconds.
+void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) {
+ if (request->has_param() && request->param().echo_deadline()) {
+ gpr_timespec deadline = gpr_inf_future;
+ if (context->absolute_deadline() != system_clock::time_point::max()) {
+ Timepoint2Timespec(context->absolute_deadline(), &deadline);
+ }
+ response->mutable_param()->set_request_deadline(deadline.tv_sec);
+ }
+}
+} // namespace
class TestServiceImpl : public TestService::Service {
public:
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) {
response->set_message(request->message());
+ MaybeEchoDeadline(context, request, response);
return Status::OK;
}
@@ -179,6 +202,71 @@ TEST_F(End2endTest, RpcDeadlineExpires) {
delete stub;
}
+// Set a long but finite deadline.
+TEST_F(End2endTest, RpcLongDeadline) {
+ std::shared_ptr<ChannelInterface> channel =
+ CreateChannel(server_address_.str(), ChannelArguments());
+ TestService::Stub* stub = TestService::NewStub(channel);
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::hours(1);
+ context.set_absolute_deadline(deadline);
+ Status s = stub->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.IsOk());
+
+ delete stub;
+}
+
+// Ask server to echo back the deadline it sees.
+TEST_F(End2endTest, EchoDeadline) {
+ std::shared_ptr<ChannelInterface> channel =
+ CreateChannel(server_address_.str(), ChannelArguments());
+ TestService::Stub* stub = TestService::NewStub(channel);
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ request.mutable_param()->set_echo_deadline(true);
+
+ ClientContext context;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::seconds(100);
+ context.set_absolute_deadline(deadline);
+ Status s = stub->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.IsOk());
+ gpr_timespec sent_deadline;
+ Timepoint2Timespec(deadline, &sent_deadline);
+ // Allow 1 second error.
+ EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
+ EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
+
+ delete stub;
+}
+
+// Ask server to echo back the deadline it sees. The rpc has no deadline.
+TEST_F(End2endTest, EchoDeadlineForNoDeadlineRpc) {
+ std::shared_ptr<ChannelInterface> channel =
+ CreateChannel(server_address_.str(), ChannelArguments());
+ TestService::Stub* stub = TestService::NewStub(channel);
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ request.mutable_param()->set_echo_deadline(true);
+
+ ClientContext context;
+ Status s = stub->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.IsOk());
+ EXPECT_EQ(response.param().request_deadline(), gpr_inf_future.tv_sec);
+
+ delete stub;
+}
+
TEST_F(End2endTest, UnimplementedRpc) {
std::shared_ptr<ChannelInterface> channel =
CreateChannel(server_address_.str(), ChannelArguments());
@@ -300,6 +388,7 @@ TEST_F(End2endTest, BidiStream) {
delete stub;
}
+} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
diff --git a/test/cpp/util/echo.proto b/test/cpp/util/echo.proto
index abce7ad03a..1240399bf8 100644
--- a/test/cpp/util/echo.proto
+++ b/test/cpp/util/echo.proto
@@ -2,12 +2,22 @@ syntax = "proto2";
package grpc.cpp.test.util;
+message RequestParams {
+ optional bool echo_deadline = 1;
+}
+
message EchoRequest {
optional string message = 1;
+ optional RequestParams param = 2;
+}
+
+message ResponseParams {
+ optional int64 request_deadline = 1;
}
message EchoResponse {
optional string message = 1;
+ optional ResponseParams param = 2;
}
service TestService {
@@ -15,6 +25,5 @@ service TestService {
rpc RequestStream(stream EchoRequest) returns (EchoResponse);
rpc ResponseStream(EchoRequest) returns (stream EchoResponse);
rpc BidiStream(stream EchoRequest) returns (stream EchoResponse);
- rpc Unimplemented(EchoRequest) returns (EchoResponse) {
- }
+ rpc Unimplemented(EchoRequest) returns (EchoResponse);
}
diff --git a/test/cpp/util/time_test.cc b/test/cpp/util/time_test.cc
index 97499fed28..c571808633 100644
--- a/test/cpp/util/time_test.cc
+++ b/test/cpp/util/time_test.cc
@@ -62,5 +62,11 @@ TEST_F(TimeTest, AbsolutePointTest) {
EXPECT_TRUE(tp == tp_converted_2);
}
+// gpr_inf_future is treated specially and mapped to time_point::max()
+TEST_F(TimeTest, InfFuture) {
+ EXPECT_EQ(system_clock::time_point::max(),
+ Timespec2Timepoint(gpr_inf_future));
+}
+
} // namespace
} // namespace grpc