nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 1 | /* |
| 2 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 3 | * Copyright 2015 gRPC authors. |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 4 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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 |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 8 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 10 | * |
Jan Tattermusch | 7897ae9 | 2017-06-07 22:57:36 +0200 | [diff] [blame] | 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. |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 16 | * |
| 17 | */ |
| 18 | |
Nicolas "Pixel" Noble | d51d121 | 2016-01-31 11:33:19 +0100 | [diff] [blame] | 19 | #include <ruby/ruby.h> |
Nicolas "Pixel" Noble | 9fcdc87 | 2016-05-05 06:15:34 +0200 | [diff] [blame] | 20 | |
Nicolas "Pixel" Noble | d51d121 | 2016-01-31 11:33:19 +0100 | [diff] [blame] | 21 | #include "rb_grpc_imports.generated.h" |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 22 | #include "rb_server.h" |
| 23 | |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 24 | #include <grpc/grpc.h> |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 25 | #include <grpc/grpc_security.h> |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 26 | #include <grpc/support/atm.h> |
murgatroid99 | 9acc40f | 2016-06-30 13:54:09 -0700 | [diff] [blame] | 27 | #include <grpc/support/log.h> |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 28 | #include "rb_byte_buffer.h" |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 29 | #include "rb_call.h" |
| 30 | #include "rb_channel_args.h" |
| 31 | #include "rb_completion_queue.h" |
| 32 | #include "rb_grpc.h" |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 33 | #include "rb_server_credentials.h" |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 34 | |
Yuki Yugui Sonoda | a7d369e | 2015-04-11 11:48:36 +0900 | [diff] [blame] | 35 | /* grpc_rb_cServer is the ruby class that proxies grpc_server. */ |
Yuki Yugui Sonoda | 3c88e5d | 2015-04-16 20:09:00 +0900 | [diff] [blame] | 36 | static VALUE grpc_rb_cServer = Qnil; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 37 | |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 38 | /* id_at is the constructor method of the ruby standard Time class. */ |
| 39 | static ID id_at; |
| 40 | |
Tim Emiola | 934ae9a | 2015-08-31 09:42:59 -0700 | [diff] [blame] | 41 | /* id_insecure_server is used to indicate that a server is insecure */ |
| 42 | static VALUE id_insecure_server; |
| 43 | |
murgatroid99 | 1fa96c5 | 2016-06-13 10:48:22 -0700 | [diff] [blame] | 44 | /* grpc_rb_server wraps a grpc_server. */ |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 45 | typedef struct grpc_rb_server { |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 46 | /* The actual server */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 47 | grpc_server* wrapped; |
| 48 | grpc_completion_queue* queue; |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 49 | int shutdown_and_notify_done; |
| 50 | int destroy_done; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 51 | } grpc_rb_server; |
| 52 | |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 53 | static void grpc_rb_server_maybe_shutdown_and_notify(grpc_rb_server* server, |
| 54 | gpr_timespec deadline) { |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 55 | grpc_event ev; |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 56 | void* tag = &ev; |
| 57 | if (!server->shutdown_and_notify_done) { |
| 58 | server->shutdown_and_notify_done = 1; |
Alex Polcyn | a868c04 | 2016-12-05 18:49:08 +0000 | [diff] [blame] | 59 | if (server->wrapped != NULL) { |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 60 | grpc_server_shutdown_and_notify(server->wrapped, server->queue, tag); |
| 61 | ev = rb_completion_queue_pluck(server->queue, tag, deadline, NULL); |
Alex Polcyn | a868c04 | 2016-12-05 18:49:08 +0000 | [diff] [blame] | 62 | if (ev.type == GRPC_QUEUE_TIMEOUT) { |
| 63 | grpc_server_cancel_all_calls(server->wrapped); |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 64 | ev = rb_completion_queue_pluck( |
| 65 | server->queue, tag, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); |
Alex Polcyn | a868c04 | 2016-12-05 18:49:08 +0000 | [diff] [blame] | 66 | } |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 67 | if (ev.type != GRPC_OP_COMPLETE) { |
| 68 | gpr_log(GPR_INFO, |
| 69 | "GRPC_RUBY: bad grpc_server_shutdown_and_notify result:%d", |
| 70 | ev.type); |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | static void grpc_rb_server_maybe_destroy(grpc_rb_server* server) { |
| 77 | // This can be started by app or implicitly by GC. Avoid a race between these. |
| 78 | if (!server->destroy_done) { |
| 79 | server->destroy_done = 1; |
| 80 | if (server->wrapped != NULL) { |
Alex Polcyn | a868c04 | 2016-12-05 18:49:08 +0000 | [diff] [blame] | 81 | grpc_server_destroy(server->wrapped); |
| 82 | grpc_rb_completion_queue_destroy(server->queue); |
| 83 | server->wrapped = NULL; |
| 84 | server->queue = NULL; |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 85 | } |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 86 | } |
| 87 | } |
| 88 | |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 89 | /* Destroys server instances. */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 90 | static void grpc_rb_server_free(void* p) { |
| 91 | grpc_rb_server* svr = NULL; |
murgatroid99 | 5ea4a99 | 2016-06-13 10:36:41 -0700 | [diff] [blame] | 92 | gpr_timespec deadline; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 93 | if (p == NULL) { |
| 94 | return; |
| 95 | }; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 96 | svr = (grpc_rb_server*)p; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 97 | |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 98 | deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), |
| 99 | gpr_time_from_seconds(2, GPR_TIMESPAN)); |
murgatroid99 | 5ea4a99 | 2016-06-13 10:36:41 -0700 | [diff] [blame] | 100 | |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 101 | grpc_rb_server_maybe_shutdown_and_notify(svr, deadline); |
| 102 | grpc_rb_server_maybe_destroy(svr); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 103 | |
| 104 | xfree(p); |
| 105 | } |
| 106 | |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 107 | static const rb_data_type_t grpc_rb_server_data_type = { |
| 108 | "grpc_server", |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 109 | {GRPC_RB_GC_NOT_MARKED, |
| 110 | grpc_rb_server_free, |
| 111 | GRPC_RB_MEMSIZE_UNAVAILABLE, |
murgatroid99 | 87afb5d | 2015-07-16 16:01:02 -0700 | [diff] [blame] | 112 | {NULL, NULL}}, |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 113 | NULL, |
| 114 | NULL, |
Tim Emiola | 9161a82 | 2015-11-11 15:58:44 -0800 | [diff] [blame] | 115 | #ifdef RUBY_TYPED_FREE_IMMEDIATELY |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 116 | /* It is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because the free |
| 117 | * function would block and we might want to unlock GVL |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 118 | * TODO(yugui) Unlock GVL? |
| 119 | */ |
Tim Emiola | 9161a82 | 2015-11-11 15:58:44 -0800 | [diff] [blame] | 120 | 0, |
| 121 | #endif |
| 122 | }; |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 123 | |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 124 | /* Allocates grpc_rb_server instances. */ |
| 125 | static VALUE grpc_rb_server_alloc(VALUE cls) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 126 | grpc_rb_server* wrapper = ALLOC(grpc_rb_server); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 127 | wrapper->wrapped = NULL; |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 128 | wrapper->destroy_done = 0; |
| 129 | wrapper->shutdown_and_notify_done = 0; |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 130 | return TypedData_Wrap_Struct(cls, &grpc_rb_server_data_type, wrapper); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 131 | } |
| 132 | |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 133 | /* |
| 134 | call-seq: |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 135 | server = Server.new({'arg1': 'value1'}) |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 136 | |
| 137 | Initializes server instances. */ |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 138 | static VALUE grpc_rb_server_init(VALUE self, VALUE channel_args) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 139 | grpc_completion_queue* cq = NULL; |
| 140 | grpc_rb_server* wrapper = NULL; |
| 141 | grpc_server* srv = NULL; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 142 | grpc_channel_args args; |
| 143 | MEMZERO(&args, grpc_channel_args, 1); |
Alexander Polcyn | 2a9b5d7 | 2017-04-14 12:10:55 -0700 | [diff] [blame] | 144 | |
| 145 | grpc_ruby_once_init(); |
| 146 | |
murgatroid99 | ce67bff | 2017-04-19 15:54:27 -0700 | [diff] [blame] | 147 | cq = grpc_completion_queue_create_for_pluck(NULL); |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 148 | TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, |
| 149 | wrapper); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 150 | grpc_rb_hash_convert_to_channel_args(channel_args, &args); |
Nicolas "Pixel" Noble | f75df57 | 2015-08-07 22:09:42 +0200 | [diff] [blame] | 151 | srv = grpc_server_create(&args, NULL); |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 152 | |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 153 | if (args.args != NULL) { |
Craig Tiller | b5dcec5 | 2015-01-13 11:13:42 -0800 | [diff] [blame] | 154 | xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */ |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 155 | } |
| 156 | if (srv == NULL) { |
| 157 | rb_raise(rb_eRuntimeError, "could not create a gRPC server, not sure why"); |
| 158 | } |
Nicolas "Pixel" Noble | f75df57 | 2015-08-07 22:09:42 +0200 | [diff] [blame] | 159 | grpc_server_register_completion_queue(srv, cq, NULL); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 160 | wrapper->wrapped = srv; |
murgatroid99 | d595fb6 | 2016-05-16 14:53:13 -0700 | [diff] [blame] | 161 | wrapper->queue = cq; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 162 | |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 163 | return self; |
| 164 | } |
| 165 | |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 166 | /* request_call_stack holds various values used by the |
| 167 | * grpc_rb_server_request_call function */ |
| 168 | typedef struct request_call_stack { |
| 169 | grpc_call_details details; |
| 170 | grpc_metadata_array md_ary; |
| 171 | } request_call_stack; |
| 172 | |
| 173 | /* grpc_request_call_stack_init ensures the request_call_stack is properly |
| 174 | * initialized */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 175 | static void grpc_request_call_stack_init(request_call_stack* st) { |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 176 | MEMZERO(st, request_call_stack, 1); |
| 177 | grpc_metadata_array_init(&st->md_ary); |
| 178 | grpc_call_details_init(&st->details); |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | /* grpc_request_call_stack_cleanup ensures the request_call_stack is properly |
| 182 | * cleaned up */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 183 | static void grpc_request_call_stack_cleanup(request_call_stack* st) { |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 184 | grpc_metadata_array_destroy(&st->md_ary); |
| 185 | grpc_call_details_destroy(&st->details); |
| 186 | } |
| 187 | |
| 188 | /* call-seq: |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 189 | server.request_call |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 190 | |
| 191 | Requests notification of a new call on a server. */ |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 192 | static VALUE grpc_rb_server_request_call(VALUE self) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 193 | grpc_rb_server* s = NULL; |
| 194 | grpc_call* call = NULL; |
Craig Tiller | c4440d9 | 2015-05-08 16:52:51 -0700 | [diff] [blame] | 195 | grpc_event ev; |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 196 | grpc_call_error err; |
| 197 | request_call_stack st; |
| 198 | VALUE result; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 199 | void* tag = (void*)&st; |
| 200 | grpc_completion_queue* call_queue = |
Sree Kuchibhotla | 8d8bb7a | 2017-03-22 12:37:29 -0700 | [diff] [blame] | 201 | grpc_completion_queue_create_for_pluck(NULL); |
Craig Tiller | 94329d0 | 2015-07-23 09:52:11 -0700 | [diff] [blame] | 202 | gpr_timespec deadline; |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 203 | |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 204 | TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 205 | if (s->wrapped == NULL) { |
Tim Emiola | b1fa5d4 | 2015-06-11 09:35:06 -0700 | [diff] [blame] | 206 | rb_raise(rb_eRuntimeError, "destroyed!"); |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 207 | return Qnil; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 208 | } |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 209 | grpc_request_call_stack_init(&st); |
| 210 | /* call grpc_server_request_call, then wait for it to complete using |
| 211 | * pluck_event */ |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 212 | err = grpc_server_request_call(s->wrapped, &call, &st.details, &st.md_ary, |
| 213 | call_queue, s->queue, tag); |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 214 | if (err != GRPC_CALL_OK) { |
| 215 | grpc_request_call_stack_cleanup(&st); |
| 216 | rb_raise(grpc_rb_eCallError, |
| 217 | "grpc_server_request_call failed: %s (code=%d)", |
| 218 | grpc_call_error_detail_of(err), err); |
| 219 | return Qnil; |
| 220 | } |
| 221 | |
| 222 | ev = rb_completion_queue_pluck(s->queue, tag, |
murgatroid99 | 5ea4a99 | 2016-06-13 10:36:41 -0700 | [diff] [blame] | 223 | gpr_inf_future(GPR_CLOCK_REALTIME), NULL); |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 224 | if (!ev.success) { |
| 225 | grpc_request_call_stack_cleanup(&st); |
| 226 | rb_raise(grpc_rb_eCallError, "request_call completion failed"); |
| 227 | return Qnil; |
| 228 | } |
| 229 | |
| 230 | /* build the NewServerRpc struct result */ |
| 231 | deadline = gpr_convert_clock_type(st.details.deadline, GPR_CLOCK_REALTIME); |
| 232 | result = rb_struct_new( |
Craig Tiller | 7c70b6c | 2017-01-23 07:48:42 -0800 | [diff] [blame] | 233 | grpc_rb_sNewServerRpc, grpc_rb_slice_to_ruby_string(st.details.method), |
| 234 | grpc_rb_slice_to_ruby_string(st.details.host), |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 235 | rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec), |
Eric Richardson | 8e769fd | 2016-07-08 12:36:54 -0400 | [diff] [blame] | 236 | INT2NUM(deadline.tv_nsec / 1000)), |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 237 | grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call, call_queue), |
| 238 | NULL); |
| 239 | grpc_request_call_stack_cleanup(&st); |
| 240 | return result; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 241 | } |
| 242 | |
| 243 | static VALUE grpc_rb_server_start(VALUE self) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 244 | grpc_rb_server* s = NULL; |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 245 | TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 246 | if (s->wrapped == NULL) { |
Tim Emiola | b1fa5d4 | 2015-06-11 09:35:06 -0700 | [diff] [blame] | 247 | rb_raise(rb_eRuntimeError, "destroyed!"); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 248 | } else { |
| 249 | grpc_server_start(s->wrapped); |
| 250 | } |
| 251 | return Qnil; |
| 252 | } |
| 253 | |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 254 | static VALUE grpc_rb_server_shutdown_and_notify(VALUE self, VALUE timeout) { |
murgatroid99 | 5ea4a99 | 2016-06-13 10:36:41 -0700 | [diff] [blame] | 255 | gpr_timespec deadline; |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 256 | grpc_rb_server* s = NULL; |
Tim Emiola | b1fa5d4 | 2015-06-11 09:35:06 -0700 | [diff] [blame] | 257 | |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 258 | TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 259 | if (TYPE(timeout) == T_NIL) { |
| 260 | deadline = gpr_inf_future(GPR_CLOCK_REALTIME); |
| 261 | } else { |
| 262 | deadline = grpc_rb_time_timeval(timeout, /* absolute time*/ 0); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 263 | } |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 264 | |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 265 | grpc_rb_server_maybe_shutdown_and_notify(s, deadline); |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 266 | |
| 267 | return Qnil; |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 268 | } |
| 269 | |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 270 | /* |
| 271 | call-seq: |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 272 | server = Server.new({'arg1': 'value1'}) |
| 273 | ... // do stuff with server |
| 274 | ... |
| 275 | ... // initiate server shutdown |
| 276 | server.shutdown_and_notify(timeout) |
| 277 | ... // to shutdown the server |
| 278 | server.destroy() |
| 279 | |
| 280 | Destroys server instances. */ |
| 281 | static VALUE grpc_rb_server_destroy(VALUE self) { |
| 282 | grpc_rb_server* s = NULL; |
| 283 | TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); |
| 284 | grpc_rb_server_maybe_destroy(s); |
| 285 | return Qnil; |
| 286 | } |
| 287 | |
| 288 | /* |
| 289 | call-seq: |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 290 | // insecure port |
| 291 | insecure_server = Server.new(cq, {'arg1': 'value1'}) |
Tim Emiola | 643ebb6 | 2015-08-31 09:50:48 -0700 | [diff] [blame] | 292 | insecure_server.add_http2_port('mydomain:50051', :this_port_is_insecure) |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 293 | |
| 294 | // secure port |
| 295 | server_creds = ... |
Tim Emiola | 3a0d976 | 2015-03-05 12:43:24 -0800 | [diff] [blame] | 296 | secure_server = Server.new(cq, {'arg1': 'value1'}) |
remi Taylor | 47b7bd9 | 2015-05-24 15:10:01 -0700 | [diff] [blame] | 297 | secure_server.add_http_port('mydomain:50051', server_creds) |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 298 | |
| 299 | Adds a http2 port to server */ |
Tim Emiola | 934ae9a | 2015-08-31 09:42:59 -0700 | [diff] [blame] | 300 | static VALUE grpc_rb_server_add_http2_port(VALUE self, VALUE port, |
| 301 | VALUE rb_creds) { |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 302 | grpc_rb_server* s = NULL; |
| 303 | grpc_server_credentials* creds = NULL; |
Tim Emiola | 0a7d858 | 2015-01-26 12:30:51 -0800 | [diff] [blame] | 304 | int recvd_port = 0; |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 305 | |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 306 | TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 307 | if (s->wrapped == NULL) { |
Tim Emiola | b1fa5d4 | 2015-06-11 09:35:06 -0700 | [diff] [blame] | 308 | rb_raise(rb_eRuntimeError, "destroyed!"); |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 309 | return Qnil; |
Tim Emiola | 934ae9a | 2015-08-31 09:42:59 -0700 | [diff] [blame] | 310 | } else if (TYPE(rb_creds) == T_SYMBOL) { |
| 311 | if (id_insecure_server != SYM2ID(rb_creds)) { |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 312 | rb_raise(rb_eTypeError, "bad creds symbol, want :this_port_is_insecure"); |
Tim Emiola | 934ae9a | 2015-08-31 09:42:59 -0700 | [diff] [blame] | 313 | return Qnil; |
| 314 | } |
Craig Tiller | c5ae3eb | 2015-08-03 10:42:22 -0700 | [diff] [blame] | 315 | recvd_port = |
| 316 | grpc_server_add_insecure_http2_port(s->wrapped, StringValueCStr(port)); |
Tim Emiola | 0a7d858 | 2015-01-26 12:30:51 -0800 | [diff] [blame] | 317 | if (recvd_port == 0) { |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 318 | rb_raise(rb_eRuntimeError, |
| 319 | "could not add port %s to server, not sure why", |
| 320 | StringValueCStr(port)); |
| 321 | } |
Tim Emiola | 3a0d976 | 2015-03-05 12:43:24 -0800 | [diff] [blame] | 322 | } else { |
| 323 | creds = grpc_rb_get_wrapped_server_credentials(rb_creds); |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 324 | recvd_port = grpc_server_add_secure_http2_port( |
| 325 | s->wrapped, StringValueCStr(port), creds); |
Tim Emiola | 0a7d858 | 2015-01-26 12:30:51 -0800 | [diff] [blame] | 326 | if (recvd_port == 0) { |
nnoble | 0c475f0 | 2014-12-05 15:37:39 -0800 | [diff] [blame] | 327 | rb_raise(rb_eRuntimeError, |
| 328 | "could not add secure port %s to server, not sure why", |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 329 | StringValueCStr(port)); |
| 330 | } |
| 331 | } |
Tim Emiola | 0a7d858 | 2015-01-26 12:30:51 -0800 | [diff] [blame] | 332 | return INT2NUM(recvd_port); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 333 | } |
| 334 | |
Tim Emiola | 409e6c8 | 2015-02-17 17:46:35 -0800 | [diff] [blame] | 335 | void Init_grpc_server() { |
Yuki Yugui Sonoda | a7d369e | 2015-04-11 11:48:36 +0900 | [diff] [blame] | 336 | grpc_rb_cServer = |
| 337 | rb_define_class_under(grpc_rb_mGrpcCore, "Server", rb_cObject); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 338 | |
| 339 | /* Allocates an object managed by the ruby runtime */ |
Yuki Yugui Sonoda | a7d369e | 2015-04-11 11:48:36 +0900 | [diff] [blame] | 340 | rb_define_alloc_func(grpc_rb_cServer, grpc_rb_server_alloc); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 341 | |
| 342 | /* Provides a ruby constructor and support for dup/clone. */ |
murgatroid99 | ec1588b | 2016-06-06 15:37:45 -0700 | [diff] [blame] | 343 | rb_define_method(grpc_rb_cServer, "initialize", grpc_rb_server_init, 1); |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 344 | rb_define_method(grpc_rb_cServer, "initialize_copy", grpc_rb_cannot_init_copy, |
| 345 | 1); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 346 | |
| 347 | /* Add the server methods. */ |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 348 | rb_define_method(grpc_rb_cServer, "request_call", grpc_rb_server_request_call, |
| 349 | 0); |
Yuki Yugui Sonoda | a7d369e | 2015-04-11 11:48:36 +0900 | [diff] [blame] | 350 | rb_define_method(grpc_rb_cServer, "start", grpc_rb_server_start, 0); |
Alexander Polcyn | 7b87bab | 2018-01-22 22:31:38 -0800 | [diff] [blame] | 351 | rb_define_method(grpc_rb_cServer, "shutdown_and_notify", |
| 352 | grpc_rb_server_shutdown_and_notify, 1); |
| 353 | rb_define_method(grpc_rb_cServer, "destroy", grpc_rb_server_destroy, 0); |
Yuki Yugui Sonoda | a7d369e | 2015-04-11 11:48:36 +0900 | [diff] [blame] | 354 | rb_define_alias(grpc_rb_cServer, "close", "destroy"); |
| 355 | rb_define_method(grpc_rb_cServer, "add_http2_port", |
Sree Kuchibhotla | 98ab520 | 2017-03-03 18:28:47 -0800 | [diff] [blame] | 356 | grpc_rb_server_add_http2_port, 2); |
Tim Emiola | 48b36b5 | 2015-03-28 15:15:03 -0700 | [diff] [blame] | 357 | id_at = rb_intern("at"); |
Tim Emiola | 934ae9a | 2015-08-31 09:42:59 -0700 | [diff] [blame] | 358 | id_insecure_server = rb_intern("this_port_is_insecure"); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 359 | } |
| 360 | |
| 361 | /* Gets the wrapped server from the ruby wrapper */ |
Craig Tiller | baa14a9 | 2017-11-03 09:09:36 -0700 | [diff] [blame] | 362 | grpc_server* grpc_rb_get_wrapped_server(VALUE v) { |
| 363 | grpc_rb_server* wrapper = NULL; |
Yuki Yugui Sonoda | 9232f12 | 2015-04-12 16:39:37 +0900 | [diff] [blame] | 364 | TypedData_Get_Struct(v, grpc_rb_server, &grpc_rb_server_data_type, wrapper); |
nnoble | 097ef9b | 2014-12-01 17:06:10 -0800 | [diff] [blame] | 365 | return wrapper->wrapped; |
| 366 | } |