diff options
author | Craig Tiller <craig.tiller@gmail.com> | 2015-05-13 16:46:55 -0700 |
---|---|---|
committer | Craig Tiller <craig.tiller@gmail.com> | 2015-05-17 14:33:33 -0700 |
commit | 09600be0a56774d11fd575b5a80a1e8cfc7d13a2 (patch) | |
tree | 9fd5eaf57527738b0bd88f72484b4df36b48e387 /src | |
parent | 0596621ec2b8c79b39fdffa12132b445eea8e49f (diff) |
Ensure that there's always a poller for completion
The C core uses completion_queue_next as a directive that progress should be made on requests bound to that cq.
If nobody is polling for completion, then a deadlock can occur (client needs to do work, but we're blocked waiting for the server).
There is no scope for this to occur using the idiomatic layers (as far as I can tell), but these low level tests need to be massaged.
Diffstat (limited to 'src')
-rw-r--r-- | src/ruby/spec/client_server_spec.rb | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb index 68af79f907..b247882241 100644 --- a/src/ruby/spec/client_server_spec.rb +++ b/src/ruby/spec/client_server_spec.rb @@ -74,6 +74,12 @@ shared_examples 'basic GRPC message delivery is OK' do it 'servers receive requests from clients and can respond' do call = new_client_call + server_call = nil + + server_thread = Thread.new do + server_call = server_allows_client_to_proceed + end + client_ops = { CallOps::SEND_INITIAL_METADATA => {}, CallOps::SEND_MESSAGE => sent_message @@ -84,7 +90,7 @@ shared_examples 'basic GRPC message delivery is OK' do expect(batch_result.send_message).to be true # confirm the server can read the inbound message - server_call = server_allows_client_to_proceed + server_thread.join server_ops = { CallOps::RECV_MESSAGE => nil } @@ -95,6 +101,12 @@ shared_examples 'basic GRPC message delivery is OK' do it 'responses written by servers are received by the client' do call = new_client_call + server_call = nil + + server_thread = Thread.new do + server_call = server_allows_client_to_proceed + end + client_ops = { CallOps::SEND_INITIAL_METADATA => {}, CallOps::SEND_MESSAGE => sent_message @@ -105,7 +117,7 @@ shared_examples 'basic GRPC message delivery is OK' do expect(batch_result.send_message).to be true # confirm the server can read the inbound message - server_call = server_allows_client_to_proceed + server_thread.join server_ops = { CallOps::RECV_MESSAGE => nil, CallOps::SEND_MESSAGE => reply_text @@ -118,6 +130,12 @@ shared_examples 'basic GRPC message delivery is OK' do it 'servers can ignore a client write and send a status' do call = new_client_call + server_call = nil + + server_thread = Thread.new do + server_call = server_allows_client_to_proceed + end + client_ops = { CallOps::SEND_INITIAL_METADATA => {}, CallOps::SEND_MESSAGE => sent_message @@ -129,7 +147,7 @@ shared_examples 'basic GRPC message delivery is OK' do # confirm the server can read the inbound message the_status = Struct::Status.new(StatusCodes::OK, 'OK') - server_call = server_allows_client_to_proceed + server_thread.join server_ops = { CallOps::SEND_STATUS_FROM_SERVER => the_status } @@ -141,6 +159,12 @@ shared_examples 'basic GRPC message delivery is OK' do it 'completes calls by sending status to client and server' do call = new_client_call + server_call = nil + + server_thread = Thread.new do + server_call = server_allows_client_to_proceed + end + client_ops = { CallOps::SEND_INITIAL_METADATA => {}, CallOps::SEND_MESSAGE => sent_message @@ -152,7 +176,7 @@ shared_examples 'basic GRPC message delivery is OK' do # confirm the server can read the inbound message and respond the_status = Struct::Status.new(StatusCodes::OK, 'OK', {}) - server_call = server_allows_client_to_proceed + server_thread.join server_ops = { CallOps::RECV_MESSAGE => nil, CallOps::SEND_MESSAGE => reply_text, @@ -221,6 +245,11 @@ shared_examples 'GRPC metadata delivery works OK' do it 'sends all the metadata pairs when keys and values are valid' do @valid_metadata.each do |md| + recvd_rpc = nil + rcv_thread = Thread.new do + recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + end + call = new_client_call client_ops = { CallOps::SEND_INITIAL_METADATA => md @@ -230,7 +259,7 @@ shared_examples 'GRPC metadata delivery works OK' do expect(batch_result.send_metadata).to be true # confirm the server can receive the client metadata - recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + rcv_thread.join expect(recvd_rpc).to_not eq nil recvd_md = recvd_rpc.metadata replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }] @@ -257,6 +286,11 @@ shared_examples 'GRPC metadata delivery works OK' do it 'raises an exception if a metadata key is invalid' do @bad_keys.each do |md| + recvd_rpc = nil + rcv_thread = Thread.new do + recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + end + call = new_client_call # client signals that it's done sending metadata to allow server to # respond @@ -266,7 +300,7 @@ shared_examples 'GRPC metadata delivery works OK' do call.run_batch(@client_queue, @client_tag, deadline, client_ops) # server gets the invocation - recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + rcv_thread.join expect(recvd_rpc).to_not eq nil server_ops = { CallOps::SEND_INITIAL_METADATA => md @@ -280,6 +314,11 @@ shared_examples 'GRPC metadata delivery works OK' do end it 'sends an empty hash if no metadata is added' do + recvd_rpc = nil + rcv_thread = Thread.new do + recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + end + call = new_client_call # client signals that it's done sending metadata to allow server to # respond @@ -289,7 +328,7 @@ shared_examples 'GRPC metadata delivery works OK' do call.run_batch(@client_queue, @client_tag, deadline, client_ops) # server gets the invocation but sends no metadata back - recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + rcv_thread.join expect(recvd_rpc).to_not eq nil server_call = recvd_rpc.call server_ops = { @@ -308,6 +347,11 @@ shared_examples 'GRPC metadata delivery works OK' do it 'sends all the pairs when keys and values are valid' do @valid_metadata.each do |md| + recvd_rpc = nil + rcv_thread = Thread.new do + recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + end + call = new_client_call # client signals that it's done sending metadata to allow server to # respond @@ -317,7 +361,7 @@ shared_examples 'GRPC metadata delivery works OK' do call.run_batch(@client_queue, @client_tag, deadline, client_ops) # server gets the invocation but sends no metadata back - recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline) + rcv_thread.join expect(recvd_rpc).to_not eq nil server_call = recvd_rpc.call server_ops = { |