rb_server.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <ruby/ruby.h>
20 
21 #include "rb_server.h"
22 
23 #include "rb_byte_buffer.h"
24 #include "rb_call.h"
25 #include "rb_channel_args.h"
26 #include "rb_completion_queue.h"
27 #include "rb_grpc.h"
29 #include "rb_server_credentials.h"
31 
32 #include <grpc/grpc.h>
33 #include <grpc/grpc_security.h>
34 #include <grpc/support/atm.h>
35 #include <grpc/support/log.h>
36 
37 /* grpc_rb_cServer is the ruby class that proxies grpc_server. */
38 static VALUE grpc_rb_cServer = Qnil;
39 
40 /* id_at is the constructor method of the ruby standard Time class. */
41 static ID id_at;
42 
43 /* id_insecure_server is used to indicate that a server is insecure */
44 static VALUE id_insecure_server;
45 
46 /* grpc_rb_server wraps a grpc_server. */
47 typedef struct grpc_rb_server {
48  /* The actual server */
54 
56  gpr_timespec deadline) {
57  grpc_event ev;
58  void* tag = &ev;
59  if (!server->shutdown_and_notify_done) {
60  server->shutdown_and_notify_done = 1;
61  if (server->wrapped != NULL) {
63  ev = rb_completion_queue_pluck(server->queue, tag, deadline, NULL);
64  if (ev.type == GRPC_QUEUE_TIMEOUT) {
68  }
69  if (ev.type != GRPC_OP_COMPLETE) {
71  "GRPC_RUBY: bad grpc_server_shutdown_and_notify result:%d",
72  ev.type);
73  }
74  }
75  }
76 }
77 
79  // This can be started by app or implicitly by GC. Avoid a race between these.
80  if (!server->destroy_done) {
81  server->destroy_done = 1;
82  if (server->wrapped != NULL) {
83  grpc_server_destroy(server->wrapped);
85  server->wrapped = NULL;
86  server->queue = NULL;
87  }
88  }
89 }
90 
91 static void grpc_rb_server_free_internal(void* p) {
92  grpc_rb_server* svr = NULL;
93  gpr_timespec deadline;
94  if (p == NULL) {
95  return;
96  };
97  svr = (grpc_rb_server*)p;
98 
101 
104 
105  xfree(p);
106 }
107 
108 /* Destroys server instances. */
109 static void grpc_rb_server_free(void* p) {
112 }
113 
114 static const rb_data_type_t grpc_rb_server_data_type = {
115  "grpc_server",
119  {NULL, NULL}},
120  NULL,
121  NULL,
122 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
123  /* It is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because the free
124  * function would block and we might want to unlock GVL
125  * TODO(yugui) Unlock GVL?
126  */
127  0,
128 #endif
129 };
130 
131 /* Allocates grpc_rb_server instances. */
132 static VALUE grpc_rb_server_alloc(VALUE cls) {
133  grpc_ruby_init();
135  wrapper->wrapped = NULL;
136  wrapper->destroy_done = 0;
137  wrapper->shutdown_and_notify_done = 0;
138  return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper);
139 }
140 
141 /*
142  call-seq:
143  server = Server.new({'arg1': 'value1'})
144 
145  Initializes server instances. */
146 static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) {
147  grpc_completion_queue* cq = NULL;
148  grpc_rb_server* wrapper = NULL;
149  grpc_server* srv = NULL;
151  MEMZERO(&args, grpc_channel_args, 1);
152 
154  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type,
155  wrapper);
157  srv = grpc_server_create(&args, NULL);
158 
159  if (args.args != NULL) {
160  xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */
161  }
162  if (srv == NULL) {
163  rb_raise(rb_eRuntimeError, "could not create a gRPC server, not sure why");
164  }
166  wrapper->wrapped = srv;
167  wrapper->queue = cq;
168 
169  return self;
170 }
171 
172 /* request_call_stack holds various values used by the
173  * grpc_rb_server_request_call function */
174 typedef struct request_call_stack {
178 
179 /* grpc_request_call_stack_init ensures the request_call_stack is properly
180  * initialized */
182  MEMZERO(st, request_call_stack, 1);
185 }
186 
187 /* grpc_request_call_stack_cleanup ensures the request_call_stack is properly
188  * cleaned up */
192 }
193 
194 /* call-seq:
195  server.request_call
196 
197  Requests notification of a new call on a server. */
198 static VALUE grpc_rb_server_request_call(VALUE self) {
199  grpc_rb_server* s = NULL;
200  grpc_call* call = NULL;
201  grpc_event ev;
204  VALUE result;
205  void* tag = (void*)&st;
206  grpc_completion_queue* call_queue =
208  gpr_timespec deadline;
209 
210  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
211  if (s->wrapped == NULL) {
212  rb_raise(rb_eRuntimeError, "destroyed!");
213  return Qnil;
214  }
216  /* call grpc_server_request_call, then wait for it to complete using
217  * pluck_event */
218  err = grpc_server_request_call(s->wrapped, &call, &st.details, &st.md_ary,
219  call_queue, s->queue, tag);
220  if (err != GRPC_CALL_OK) {
222  rb_raise(grpc_rb_eCallError,
223  "grpc_server_request_call failed: %s (code=%d)",
225  return Qnil;
226  }
227 
228  ev = rb_completion_queue_pluck(s->queue, tag,
230  if (!ev.success) {
232  rb_raise(grpc_rb_eCallError, "request_call completion failed");
233  return Qnil;
234  }
235 
236  /* build the NewServerRpc struct result */
238  result = rb_struct_new(
241  rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
242  INT2NUM(deadline.tv_nsec / 1000)),
244  NULL);
246  return result;
247 }
248 
249 static VALUE grpc_rb_server_start(VALUE self) {
250  grpc_rb_server* s = NULL;
251  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
252 
254  if (s->wrapped == NULL) {
255  rb_raise(rb_eRuntimeError, "destroyed!");
256  } else {
257  grpc_server_start(s->wrapped);
258  }
259  return Qnil;
260 }
261 
262 static VALUE grpc_rb_server_shutdown_and_notify(VALUE self, VALUE timeout) {
263  gpr_timespec deadline;
264  grpc_rb_server* s = NULL;
265 
266  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
267  if (TYPE(timeout) == T_NIL) {
269  } else {
270  deadline = grpc_rb_time_timeval(timeout, /* absolute time*/ 0);
271  }
272 
274 
275  return Qnil;
276 }
277 
278 /*
279  call-seq:
280  server = Server.new({'arg1': 'value1'})
281  ... // do stuff with server
282  ...
283  ... // initiate server shutdown
284  server.shutdown_and_notify(timeout)
285  ... // to shutdown the server
286  server.destroy()
287 
288  Destroys server instances. */
289 static VALUE grpc_rb_server_destroy(VALUE self) {
290  grpc_rb_server* s = NULL;
291  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
293  return Qnil;
294 }
295 
296 /*
297  call-seq:
298  // insecure port
299  insecure_server = Server.new(cq, {'arg1': 'value1'})
300  insecure_server.add_http2_port('mydomain:50051', :this_port_is_insecure)
301 
302  // secure port
303  server_creds = ...
304  secure_server = Server.new(cq, {'arg1': 'value1'})
305  secure_server.add_http_port('mydomain:50051', server_creds)
306 
307  Adds a http2 port to server */
308 static VALUE grpc_rb_server_add_http2_port(VALUE self, VALUE port,
309  VALUE rb_creds) {
310  grpc_rb_server* s = NULL;
311  grpc_server_credentials* creds = NULL;
312  int recvd_port = 0;
313 
314  TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
315  if (s->wrapped == NULL) {
316  rb_raise(rb_eRuntimeError, "destroyed!");
317  return Qnil;
318  } else if (TYPE(rb_creds) == T_SYMBOL) {
319  if (id_insecure_server != SYM2ID(rb_creds)) {
320  rb_raise(rb_eTypeError, "bad creds symbol, want :this_port_is_insecure");
321  return Qnil;
322  }
323  grpc_server_credentials* insecure_creds =
325  recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port),
326  insecure_creds);
327  grpc_server_credentials_release(insecure_creds);
328  if (recvd_port == 0) {
329  rb_raise(rb_eRuntimeError,
330  "could not add port %s to server, not sure why",
331  StringValueCStr(port));
332  }
333  } else {
334  // TODO: create a common parent class for all server-side credentials,
335  // then we can have a single method to retrieve the underlying
336  // grpc_server_credentials object, and avoid the need for this reflection
337  if (grpc_rb_is_server_credentials(rb_creds)) {
338  creds = grpc_rb_get_wrapped_server_credentials(rb_creds);
339  } else if (grpc_rb_is_xds_server_credentials(rb_creds)) {
341  } else {
342  rb_raise(rb_eTypeError,
343  "failed to create server because credentials parameter has an "
344  "invalid type, want ServerCredentials or XdsServerCredentials");
345  }
346  recvd_port =
347  grpc_server_add_http2_port(s->wrapped, StringValueCStr(port), creds);
348  if (recvd_port == 0) {
349  rb_raise(rb_eRuntimeError,
350  "could not add secure port %s to server, not sure why",
351  StringValueCStr(port));
352  }
353  }
354  return INT2NUM(recvd_port);
355 }
356 
359  rb_define_class_under(grpc_rb_mGrpcCore, "Server", rb_cObject);
360 
361  /* Allocates an object managed by the ruby runtime */
362  rb_define_alloc_func(grpc_rb_cServer, grpc_rb_server_alloc);
363 
364  /* Provides a ruby constructor and support for dup/clone. */
365  rb_define_method(grpc_rb_cServer, "initialize", grpc_rb_server_init, 1);
366  rb_define_method(grpc_rb_cServer, "initialize_copy", grpc_rb_cannot_init_copy,
367  1);
368 
369  /* Add the server methods. */
370  rb_define_method(grpc_rb_cServer, "request_call", grpc_rb_server_request_call,
371  0);
372  rb_define_method(grpc_rb_cServer, "start", grpc_rb_server_start, 0);
373  rb_define_method(grpc_rb_cServer, "shutdown_and_notify",
375  rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, 0);
376  rb_define_alias(grpc_rb_cServer, "close", "destroy");
377  rb_define_method(grpc_rb_cServer, "add_http2_port",
379  id_at = rb_intern("at");
380  id_insecure_server = rb_intern("this_port_is_insecure");
381 }
382 
383 /* Gets the wrapped server from the ruby wrapper */
385  grpc_rb_server* wrapper = NULL;
386  TypedData_Get_Struct(v, grpc_rb_server, &grpc_rb_server_data_type, wrapper);
387  return wrapper->wrapped;
388 }
rb_completion_queue.h
gpr_timespec::tv_nsec
int32_t tv_nsec
Definition: gpr_types.h:52
GPR_TIMESPAN
@ GPR_TIMESPAN
Definition: gpr_types.h:45
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
gpr_timespec::tv_sec
int64_t tv_sec
Definition: gpr_types.h:51
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
grpc_call_error
grpc_call_error
Definition: grpc_types.h:464
grpc_rb_slice_to_ruby_string
VALUE grpc_rb_slice_to_ruby_string(grpc_slice slice)
Definition: rb_byte_buffer.c:58
grpc_call_details_destroy
GRPCAPI void grpc_call_details_destroy(grpc_call_details *details)
Definition: call_details.cc:36
rb_xds_server_credentials.h
grpc_call_details_init
GRPCAPI void grpc_call_details_init(grpc_call_details *details)
Definition: call_details.cc:30
log.h
rb_grpc_imports.generated.h
GRPC_RB_MEMSIZE_UNAVAILABLE
#define GRPC_RB_MEMSIZE_UNAVAILABLE
Definition: rb_grpc.h:57
grpc_completion_queue_create_for_pluck
GRPCAPI grpc_completion_queue * grpc_completion_queue_create_for_pluck(void *reserved)
Definition: completion_queue_factory.cc:69
grpc_rb_hash_convert_to_channel_args
void grpc_rb_hash_convert_to_channel_args(VALUE src_hash, grpc_channel_args *dst)
Definition: rb_channel_args.c:139
grpc_ruby_shutdown
void grpc_ruby_shutdown()
Definition: rb_grpc.c:296
GRPC_RB_GC_NOT_MARKED
#define GRPC_RB_GC_NOT_MARKED
Definition: rb_grpc.h:48
grpc_rb_cServer
static VALUE grpc_rb_cServer
Definition: rb_server.c:38
grpc_metadata_array
Definition: grpc_types.h:579
grpc_call_details
Definition: grpc_types.h:585
grpc_rb_server_init
static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args)
Definition: rb_server.c:146
error_ref_leak.err
err
Definition: error_ref_leak.py:35
GRPC_OP_COMPLETE
@ GRPC_OP_COMPLETE
Definition: grpc_types.h:558
grpc_request_call_stack_init
static void grpc_request_call_stack_init(request_call_stack *st)
Definition: rb_server.c:181
rb_completion_queue_pluck
grpc_event rb_completion_queue_pluck(grpc_completion_queue *queue, void *tag, gpr_timespec deadline, void *reserved)
Definition: rb_completion_queue.c:75
grpc_server_create
GRPCAPI grpc_server * grpc_server_create(const grpc_channel_args *args, void *reserved)
Definition: src/core/lib/surface/server.cc:1456
GRPC_CALL_OK
@ GRPC_CALL_OK
Definition: grpc_types.h:466
grpc_server_register_completion_queue
GRPCAPI void grpc_server_register_completion_queue(grpc_server *server, grpc_completion_queue *cq, void *reserved)
Definition: src/core/lib/surface/server.cc:1466
gpr_inf_future
GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:55
xds_manager.p
p
Definition: xds_manager.py:60
grpc_security.h
grpc_call_details::method
grpc_slice method
Definition: grpc_types.h:586
grpc_rb_server_data_type
static const rb_data_type_t grpc_rb_server_data_type
Definition: rb_server.c:114
grpc_channel_args
Definition: grpc_types.h:132
_grpc_channel_wrapper::wrapped
grpc_channel * wrapped
Definition: src/php/ext/grpc/channel.h:35
grpc_rb_server::shutdown_and_notify_done
int shutdown_and_notify_done
Definition: rb_server.c:51
call
FilterStackCall * call
Definition: call.cc:750
grpc_rb_server_request_call
static VALUE grpc_rb_server_request_call(VALUE self)
Definition: rb_server.c:198
grpc_rb_server_shutdown_and_notify
static VALUE grpc_rb_server_shutdown_and_notify(VALUE self, VALUE timeout)
Definition: rb_server.c:262
grpc_request_call_stack_cleanup
static void grpc_request_call_stack_cleanup(request_call_stack *st)
Definition: rb_server.c:189
grpc_insecure_server_credentials_create
GRPCAPI grpc_server_credentials * grpc_insecure_server_credentials_create()
Definition: core/lib/security/credentials/insecure/insecure_credentials.cc:71
grpc_metadata_array_destroy
GRPCAPI void grpc_metadata_array_destroy(grpc_metadata_array *array)
Definition: metadata_array.cc:35
grpc_rb_server_free
static void grpc_rb_server_free(void *p)
Definition: rb_server.c:109
grpc_server_request_call
GRPCAPI grpc_call_error grpc_server_request_call(grpc_server *server, grpc_call **call, grpc_call_details *details, grpc_metadata_array *request_metadata, grpc_completion_queue *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void *tag_new)
Definition: src/core/lib/surface/server.cc:1526
request_call_stack::md_ary
grpc_metadata_array md_ary
Definition: rb_server.c:176
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
grpc_server_credentials_release
GRPCAPI void grpc_server_credentials_release(grpc_server_credentials *creds)
Definition: credentials.cc:95
grpc_server_add_http2_port
GRPCAPI int grpc_server_add_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds)
Definition: chttp2_server.cc:1029
grpc_rb_server_maybe_destroy
static void grpc_rb_server_maybe_destroy(grpc_rb_server *server)
Definition: rb_server.c:78
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
grpc_event
Definition: grpc_types.h:564
grpc_rb_sNewServerRpc
VALUE grpc_rb_sNewServerRpc
Definition: rb_grpc.c:246
grpc_completion_queue
Definition: completion_queue.cc:347
grpc.h
grpc_call
struct grpc_call grpc_call
Definition: grpc_types.h:70
id_insecure_server
static VALUE id_insecure_server
Definition: rb_server.c:44
grpc_rb_is_server_credentials
bool grpc_rb_is_server_credentials(VALUE v)
Definition: rb_server_credentials.c:257
rb_channel_args.h
grpc_rb_get_wrapped_xds_server_credentials
grpc_server_credentials * grpc_rb_get_wrapped_xds_server_credentials(VALUE v)
Definition: rb_xds_server_credentials.c:159
grpc_server
struct grpc_server grpc_server
Definition: grpc_types.h:65
grpc_rb_server_alloc
static VALUE grpc_rb_server_alloc(VALUE cls)
Definition: rb_server.c:132
grpc_server_destroy
GRPCAPI void grpc_server_destroy(grpc_server *server)
Definition: src/core/lib/surface/server.cc:1519
grpc_rb_server_destroy
static VALUE grpc_rb_server_destroy(VALUE self)
Definition: rb_server.c:289
wrapper
grpc_channel_wrapper * wrapper
Definition: src/php/ext/grpc/channel.h:48
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
rb_byte_buffer.h
rb_server_credentials.h
grpc_rb_server::queue
grpc_completion_queue * queue
Definition: rb_server.c:50
grpc_server_cancel_all_calls
GRPCAPI void grpc_server_cancel_all_calls(grpc_server *server)
Definition: src/core/lib/surface/server.cc:1512
tests.unit._exit_scenarios.port
port
Definition: _exit_scenarios.py:179
grpc_server_credentials
Definition: src/core/lib/security/credentials/credentials.h:259
rb_grpc.h
grpc_rb_mGrpcCore
VALUE grpc_rb_mGrpcCore
Definition: rb_grpc.c:252
grpc_rb_completion_queue_destroy
void grpc_rb_completion_queue_destroy(grpc_completion_queue *cq)
Definition: rb_completion_queue.c:59
gpr_time_add
GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:135
grpc_call_details::host
grpc_slice host
Definition: grpc_types.h:587
server
Definition: examples/python/async_streaming/server.py:1
grpc_rb_time_timeval
gpr_timespec grpc_rb_time_timeval(VALUE time, int interval)
Definition: rb_grpc.c:98
gpr_convert_clock_type
GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:241
ALLOC
#define ALLOC(class_name)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1486
grpc_rb_wrap_call
VALUE grpc_rb_wrap_call(grpc_call *c, grpc_completion_queue *q)
Definition: rb_call.c:1042
grpc_rb_cannot_init_copy
VALUE grpc_rb_cannot_init_copy(VALUE copy, VALUE self)
Definition: rb_grpc.c:80
request_call_stack
struct request_call_stack request_call_stack
grpc_rb_server_add_http2_port
static VALUE grpc_rb_server_add_http2_port(VALUE self, VALUE port, VALUE rb_creds)
Definition: rb_server.c:308
grpc_rb_server
Definition: rb_server.c:47
grpc_rb_get_wrapped_server
grpc_server * grpc_rb_get_wrapped_server(VALUE v)
Definition: rb_server.c:384
grpc_rb_server::destroy_done
int destroy_done
Definition: rb_server.c:52
grpc_server_shutdown_and_notify
GRPCAPI void grpc_server_shutdown_and_notify(grpc_server *server, grpc_completion_queue *cq, void *tag)
Definition: src/core/lib/surface/server.cc:1503
grpc_call_error_detail_of
const char * grpc_call_error_detail_of(grpc_call_error err)
Definition: rb_call.c:141
rb_call.h
grpc_rb_md_ary_to_h
VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary)
Definition: rb_call.c:515
request_call_stack::details
grpc_call_details details
Definition: rb_server.c:175
grpc_ruby_fork_guard
void grpc_ruby_fork_guard()
Definition: rb_grpc.c:261
Init_grpc_server
void Init_grpc_server()
Definition: rb_server.c:357
grpc_rb_server_free_internal
static void grpc_rb_server_free_internal(void *p)
Definition: rb_server.c:91
TYPE
#define TYPE(u, l)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:8202
grpc_rb_eCallError
VALUE grpc_rb_eCallError
Definition: rb_call.c:39
atm.h
gpr_timespec
Definition: gpr_types.h:50
grpc_event::type
grpc_completion_type type
Definition: grpc_types.h:566
grpc_rb_get_wrapped_server_credentials
grpc_server_credentials * grpc_rb_get_wrapped_server_credentials(VALUE v)
Definition: rb_server_credentials.c:248
grpc_server_start
GRPCAPI void grpc_server_start(grpc_server *server)
Definition: src/core/lib/surface/server.cc:1497
grpc_rb_server_start
static VALUE grpc_rb_server_start(VALUE self)
Definition: rb_server.c:249
grpc_rb_is_xds_server_credentials
bool grpc_rb_is_xds_server_credentials(VALUE v)
Definition: rb_xds_server_credentials.c:168
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
grpc_rb_server_maybe_shutdown_and_notify
static void grpc_rb_server_maybe_shutdown_and_notify(grpc_rb_server *server, gpr_timespec deadline)
Definition: rb_server.c:55
id_at
static ID id_at
Definition: rb_server.c:41
rb_server.h
grpc_call_details::deadline
gpr_timespec deadline
Definition: grpc_types.h:588
grpc_event::success
int success
Definition: grpc_types.h:572
GRPC_QUEUE_TIMEOUT
@ GRPC_QUEUE_TIMEOUT
Definition: grpc_types.h:556
grpc_rb_server
struct grpc_rb_server grpc_rb_server
request_call_stack
Definition: rb_server.c:174
cq
static grpc_completion_queue * cq
Definition: test/core/fling/client.cc:37
timeout
uv_timer_t timeout
Definition: libuv/docs/code/uvwget/main.c:9
grpc_ruby_init
void grpc_ruby_init()
Definition: rb_grpc.c:286
grpc_rb_server::wrapped
grpc_server * wrapped
Definition: rb_server.c:49
grpc_metadata_array_init
GRPCAPI void grpc_metadata_array_init(grpc_metadata_array *array)
Definition: metadata_array.cc:30
gpr_time_from_seconds
GPRAPI gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:123


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:06