Send RPC deadline to server in cronet header

pull/19820/head
Prashant Jaikumar 5 years ago
parent e20c2e85d8
commit e9d81fb0f2
  1. 31
      src/core/ext/transport/cronet/transport/cronet_transport.cc
  2. 26
      test/cpp/ios/CronetTests/CppCronetEnd2EndTests.mm

@ -40,6 +40,7 @@
#include "src/core/lib/surface/validate_metadata.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/timeout_encoding.h"
#include "src/core/lib/transport/transport_impl.h"
#include "third_party/objective_c/Cronet/bidirectional_stream_c.h"
@ -718,16 +719,20 @@ static void create_grpc_frame(grpc_slice_buffer* write_slice_buffer,
Convert metadata in a format that Cronet can consume
*/
static void convert_metadata_to_cronet_headers(
grpc_linked_mdelem* head, const char* host, char** pp_url,
grpc_metadata_batch* metadata, const char* host, char** pp_url,
bidirectional_stream_header** pp_headers, size_t* p_num_headers,
const char** method) {
grpc_linked_mdelem* curr = head;
grpc_linked_mdelem* curr = metadata->list.head;
/* Walk the linked list and get number of header fields */
size_t num_headers_available = 0;
while (curr != nullptr) {
curr = curr->next;
num_headers_available++;
}
grpc_millis deadline = metadata->deadline;
if (deadline != GRPC_MILLIS_INF_FUTURE) {
num_headers_available++;
}
/* Allocate enough memory. It is freed in the on_stream_ready callback
*/
bidirectional_stream_header* headers =
@ -740,7 +745,7 @@ static void convert_metadata_to_cronet_headers(
are not used for cronet.
TODO (makdharma): Eliminate need to traverse the LL second time for perf.
*/
curr = head;
curr = metadata->list.head;
size_t num_headers = 0;
while (num_headers < num_headers_available) {
grpc_mdelem mdelem = curr->md;
@ -788,6 +793,18 @@ static void convert_metadata_to_cronet_headers(
break;
}
}
if (deadline != GRPC_MILLIS_INF_FUTURE) {
char* key = grpc_slice_to_c_string(GRPC_MDSTR_GRPC_TIMEOUT);
char* value =
static_cast<char*>(gpr_malloc(GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE));
grpc_http2_encode_timeout(deadline - grpc_core::ExecCtx::Get()->Now(),
value);
headers[num_headers].key = key;
headers[num_headers].value = value;
num_headers++;
}
*p_num_headers = num_headers;
}
@ -1028,10 +1045,10 @@ static enum e_op_result execute_stream_op(struct op_and_state* oas) {
char* url = nullptr;
const char* method = "POST";
s->header_array.headers = nullptr;
convert_metadata_to_cronet_headers(stream_op->payload->send_initial_metadata
.send_initial_metadata->list.head,
t->host, &url, &s->header_array.headers,
&s->header_array.count, &method);
convert_metadata_to_cronet_headers(
stream_op->payload->send_initial_metadata.send_initial_metadata,
t->host, &url, &s->header_array.headers, &s->header_array.count,
&method);
s->header_array.capacity = s->header_array.count;
CRONET_LOG(GPR_DEBUG, "bidirectional_stream_start(%p, %s)", s->cbs, url);
bidirectional_stream_start(s->cbs, url, 0, method, &s->header_array, false);

@ -536,6 +536,32 @@ using grpc::ClientContext;
XCTAssertEqual(response.param().request_deadline(), gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
}
- (void)testEchoDeadline {
auto stub = [self getStub];
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_deadline(deadline);
Status s = stub->Echo(&context, request, &response);
XCTAssertEqual(response.message(), request.message());
XCTAssertTrue(s.ok());
gpr_timespec sent_deadline;
grpc::Timepoint2Timespec(deadline, &sent_deadline);
// We want to allow some reasonable error given:
// - request_deadline() only has 1sec resolution so the best we can do is +-1
// - if sent_deadline.tv_nsec is very close to the next second's boundary we
// can end up being off by 2 in one direction.
XCTAssertLessThanOrEqual(response.param().request_deadline() - sent_deadline.tv_sec, 2);
XCTAssertGreaterThanOrEqual(response.param().request_deadline() - sent_deadline.tv_sec, -1);
NSLog(@"request deadline: %d sent_deadline: %d", response.param().request_deadline(),
sent_deadline.tv_sec);
}
- (void)testPeer {
auto stub = [self getStub];
EchoRequest request;

Loading…
Cancel
Save