| 
					
				 | 
			
			
				@@ -210,7 +210,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   VALUE result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (s->wrapped == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rb_raise(rb_eRuntimeError, "closed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    rb_raise(rb_eRuntimeError, "destroyed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_request_call_stack_init(&st); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -259,21 +259,69 @@ static VALUE grpc_rb_server_start(VALUE self) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_rb_server *s = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (s->wrapped == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rb_raise(rb_eRuntimeError, "closed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    rb_raise(rb_eRuntimeError, "destroyed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_server_start(s->wrapped); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-static VALUE grpc_rb_server_destroy(VALUE self) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  call-seq: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cq = CompletionQueue.new 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    server = Server.new(cq, {'arg1': 'value1'}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ... // do stuff with server 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ... // to shutdown the server 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    server.destroy(cq) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ... // to shutdown the server with a timeout 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    server.destroy(cq, timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Destroys server instances. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static VALUE grpc_rb_server_destroy(int argc, VALUE *argv, VALUE self) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  VALUE cqueue = Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  VALUE timeout = Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_completion_queue *cq = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_event ev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_rb_server *s = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* "11" == 1 mandatory args, 1 (timeout) is optional */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rb_scan_args(argc, argv, "11", &cqueue, &timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq = grpc_rb_get_wrapped_completion_queue(cqueue); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (s->wrapped != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    grpc_server_shutdown(s->wrapped); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_server_shutdown_and_notify(s->wrapped, cq, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ev = grpc_rb_completion_queue_pluck_event(cqueue, Qnil, timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!ev.success) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rb_warn("server shutdown failed, there will be a LEAKED object warning"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         TODO: renable the rb_raise below. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         At the moment if the timeout is INFINITE_FUTURE as recommended, the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         pluck blocks forever, even though 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         the outstanding server_request_calls correctly fail on the other 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         thread that they are running on. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         it's almost as if calls that fail on the other thread do not get 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         cleaned up by shutdown request, even though it caused htem to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         terminate. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         rb_raise(rb_eRuntimeError, "grpc server shutdown did not succeed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         return Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         The workaround is just to use a timeout and return without really 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         shutting down the server, and rely on the grpc core garbage collection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         it down as a 'LEAKED OBJECT'. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_server_destroy(s->wrapped); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     s->wrapped = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    s->mark = Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -302,7 +350,7 @@ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (s->wrapped == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    rb_raise(rb_eRuntimeError, "closed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    rb_raise(rb_eRuntimeError, "destroyed!"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return Qnil; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else if (rb_creds == Qnil) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port)); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -315,7 +363,7 @@ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     creds = grpc_rb_get_wrapped_server_credentials(rb_creds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     recvd_port = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			                  creds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          creds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (recvd_port == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       rb_raise(rb_eRuntimeError, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                "could not add secure port %s to server, not sure why", 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -341,7 +389,7 @@ void Init_grpc_server() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rb_define_method(grpc_rb_cServer, "request_call", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    grpc_rb_server_request_call, 3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rb_define_method(grpc_rb_cServer, "start", grpc_rb_server_start, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rb_define_alias(grpc_rb_cServer, "close", "destroy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   rb_define_method(grpc_rb_cServer, "add_http2_port", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                    grpc_rb_server_add_http2_port, 
			 |