grpc 1.53.1 → 1.53.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a379c4ca9a7aaaba1fc0daf741ff674124622bf473dc48ecc8c786ba7a9246a5
4
- data.tar.gz: 87ad7e100be1406e6b5d928d9f6af684dd0f2d5bb9fc7c9b5a15ab0fed668cc8
3
+ metadata.gz: 0c237088f6035b2dc6f188374ab0531f3f3b8307f61fdc5b8a57518bc02b222c
4
+ data.tar.gz: fb1aec781fd0bf129d3740eeed7fa432b0412f29ba4ec2da79b197bb903cb1bd
5
5
  SHA512:
6
- metadata.gz: 8022d820669d96ad0669842e80a0e8cc316fdd77f0c3843e1ab8bb899ed9ea829baecf08e31c81d0bb64c55ba6afe98c8ae693d46bdeeb83f7b7f6dbe25628dc
7
- data.tar.gz: eda257dbc42d4e994f67f7efacdf8c63078808b22e1adc92ec05a5ebdd1490fc1c49b87b6e88e32954dff09dacf53deb1c5517acbc00ddd8356de2200a0ad247
6
+ metadata.gz: b62ef23a0f40e77c274ceeb11b929e6fa61cf9b7ac381524ee5be37b5c64e45b8ddb4a7188442fc0387c7296fd67b77b775af93aea877f5ccb78ed9aa0a16573
7
+ data.tar.gz: 45fc670b35416ca8a2a1f133e512576a4cdd4d72ddc97506aa2dcc7aa650a90865a6acfba41bb3cded70a126702fa5736a0ffb8dea7e1ccb83df5a6a7633f0b5
data/Makefile CHANGED
@@ -411,8 +411,8 @@ Q = @
411
411
  endif
412
412
 
413
413
  CORE_VERSION = 30.1.0
414
- CPP_VERSION = 1.53.1
415
- CSHARP_VERSION = 2.53.1
414
+ CPP_VERSION = 1.53.2
415
+ CSHARP_VERSION = 2.53.2
416
416
 
417
417
  CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
418
418
  CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -196,6 +196,7 @@ class PosixEventEngine final : public PosixEventEngineWithFdSupport,
196
196
  const DNSResolver::ResolverOptions& options) override;
197
197
  void Run(Closure* closure) override;
198
198
  void Run(absl::AnyInvocable<void()> closure) override;
199
+ // Caution!! The timer implementation cannot create any fds. See #20418.
199
200
  TaskHandle RunAfter(Duration when, Closure* closure) override;
200
201
  TaskHandle RunAfter(Duration when,
201
202
  absl::AnyInvocable<void()> closure) override;
@@ -23,7 +23,9 @@
23
23
  #include <sys/socket.h> // IWYU pragma: keep
24
24
  #include <unistd.h> // IWYU pragma: keep
25
25
 
26
+ #include <atomic>
26
27
  #include <string>
28
+ #include <tuple>
27
29
  #include <utility>
28
30
 
29
31
  #include "absl/functional/any_invocable.h"
@@ -41,6 +43,7 @@
41
43
  #include "src/core/lib/event_engine/posix_engine/tcp_socket_utils.h"
42
44
  #include "src/core/lib/event_engine/tcp_socket_utils.h"
43
45
  #include "src/core/lib/gprpp/status_helper.h"
46
+ #include "src/core/lib/gprpp/time.h"
44
47
  #include "src/core/lib/iomgr/socket_mutator.h"
45
48
 
46
49
  namespace grpc_event_engine {
@@ -133,6 +136,32 @@ void PosixEngineListenerImpl::AsyncConnectionAcceptor::NotifyOnAccept(
133
136
  switch (errno) {
134
137
  case EINTR:
135
138
  continue;
139
+ case EMFILE:
140
+ // When the process runs out of fds, accept4() returns EMFILE. When
141
+ // this happens, the connection is left in the accept queue until
142
+ // either a read event triggers the on_read callback, or time has
143
+ // passed and the accept should be re-tried regardless. This callback
144
+ // is not cancelled, so a spurious wakeup may occur even when there's
145
+ // nothing to accept. This is not a performant code path, but if an fd
146
+ // limit has been reached, the system is likely in an unhappy state
147
+ // regardless.
148
+ GRPC_LOG_EVERY_N_SEC(1, "%s",
149
+ "File descriptor limit reached. Retrying.");
150
+ handle_->NotifyOnRead(notify_on_accept_);
151
+ // Do not schedule another timer if one is already armed.
152
+ if (retry_timer_armed_.exchange(true)) return;
153
+ // Hold a ref while the retry timer is waiting, to prevent listener
154
+ // destruction and the races that would ensue.
155
+ Ref();
156
+ std::ignore =
157
+ engine_->RunAfter(grpc_core::Duration::Seconds(1), [this]() {
158
+ retry_timer_armed_.store(false);
159
+ if (!handle_->IsHandleShutdown()) {
160
+ handle_->SetReadable();
161
+ }
162
+ Unref();
163
+ });
164
+ return;
136
165
  case EAGAIN:
137
166
  case ECONNABORTED:
138
167
  handle_->NotifyOnRead(notify_on_accept_);
@@ -121,6 +121,9 @@ class PosixEngineListenerImpl
121
121
  ListenerSocketsContainer::ListenerSocket socket_;
122
122
  EventHandle* handle_;
123
123
  PosixEngineClosure* notify_on_accept_;
124
+ // Tracks the status of a backup timer to retry accept4 calls after file
125
+ // descriptor exhaustion.
126
+ std::atomic<bool> retry_timer_armed_{false};
124
127
  };
125
128
  class ListenerAsyncAcceptors : public ListenerSocketsContainer {
126
129
  public:
@@ -16,13 +16,17 @@
16
16
  //
17
17
  //
18
18
 
19
+ #include <grpc/support/port_platform.h>
20
+
21
+ #include <utility>
22
+
23
+ #include <grpc/support/atm.h>
24
+
19
25
  // FIXME: "posix" files shouldn't be depending on _GNU_SOURCE
20
26
  #ifndef _GNU_SOURCE
21
27
  #define _GNU_SOURCE
22
28
  #endif
23
29
 
24
- #include <grpc/support/port_platform.h>
25
-
26
30
  #include "src/core/lib/iomgr/port.h"
27
31
 
28
32
  #ifdef GRPC_POSIX_SOCKET_TCP_SERVER
@@ -45,6 +49,7 @@
45
49
 
46
50
  #include <grpc/byte_buffer.h>
47
51
  #include <grpc/event_engine/endpoint_config.h>
52
+ #include <grpc/event_engine/event_engine.h>
48
53
  #include <grpc/support/alloc.h>
49
54
  #include <grpc/support/log.h>
50
55
  #include <grpc/support/sync.h>
@@ -74,6 +79,8 @@
74
79
  #include "src/core/lib/transport/error_utils.h"
75
80
 
76
81
  static std::atomic<int64_t> num_dropped_connections{0};
82
+ static constexpr grpc_core::Duration kRetryAcceptWaitTime{
83
+ grpc_core::Duration::Seconds(1)};
77
84
 
78
85
  using ::grpc_event_engine::experimental::EndpointConfig;
79
86
  using ::grpc_event_engine::experimental::EventEngine;
@@ -350,22 +357,38 @@ static void on_read(void* arg, grpc_error_handle err) {
350
357
  if (fd < 0) {
351
358
  if (errno == EINTR) {
352
359
  continue;
353
- } else if (errno == EAGAIN || errno == ECONNABORTED ||
354
- errno == EWOULDBLOCK) {
360
+ }
361
+ // When the process runs out of fds, accept4() returns EMFILE. When this
362
+ // happens, the connection is left in the accept queue until either a
363
+ // read event triggers the on_read callback, or time has passed and the
364
+ // accept should be re-tried regardless. This callback is not cancelled,
365
+ // so a spurious wakeup may occur even when there's nothing to accept.
366
+ // This is not a performant code path, but if an fd limit has been
367
+ // reached, the system is likely in an unhappy state regardless.
368
+ if (errno == EMFILE) {
369
+ GRPC_LOG_EVERY_N_SEC(1, "%s",
370
+ "File descriptor limit reached. Retrying.");
371
+ grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
372
+ if (gpr_atm_full_xchg(&sp->retry_timer_armed, true)) return;
373
+ grpc_timer_init(&sp->retry_timer,
374
+ grpc_core::Timestamp::Now() + kRetryAcceptWaitTime,
375
+ &sp->retry_closure);
376
+ return;
377
+ }
378
+ if (errno == EAGAIN || errno == ECONNABORTED || errno == EWOULDBLOCK) {
355
379
  grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
356
380
  return;
381
+ }
382
+ gpr_mu_lock(&sp->server->mu);
383
+ if (!sp->server->shutdown_listeners) {
384
+ gpr_log(GPR_ERROR, "Failed accept4: %s",
385
+ grpc_core::StrError(errno).c_str());
357
386
  } else {
358
- gpr_mu_lock(&sp->server->mu);
359
- if (!sp->server->shutdown_listeners) {
360
- gpr_log(GPR_ERROR, "Failed accept4: %s",
361
- grpc_core::StrError(errno).c_str());
362
- } else {
363
- // if we have shutdown listeners, accept4 could fail, and we
364
- // needn't notify users
365
- }
366
- gpr_mu_unlock(&sp->server->mu);
367
- goto error;
387
+ // if we have shutdown listeners, accept4 could fail, and we
388
+ // needn't notify users
368
389
  }
390
+ gpr_mu_unlock(&sp->server->mu);
391
+ goto error;
369
392
  }
370
393
 
371
394
  if (sp->server->memory_quota->IsMemoryPressureHigh()) {
@@ -558,6 +581,7 @@ static grpc_error_handle clone_port(grpc_tcp_listener* listener,
558
581
  sp->port_index = listener->port_index;
559
582
  sp->fd_index = listener->fd_index + count - i;
560
583
  GPR_ASSERT(sp->emfd);
584
+ grpc_tcp_server_listener_initialize_retry_timer(sp);
561
585
  while (listener->server->tail->next != nullptr) {
562
586
  listener->server->tail = listener->server->tail->next;
563
587
  }
@@ -791,6 +815,7 @@ static void tcp_server_shutdown_listeners(grpc_tcp_server* s) {
791
815
  if (s->active_ports) {
792
816
  grpc_tcp_listener* sp;
793
817
  for (sp = s->head; sp; sp = sp->next) {
818
+ grpc_timer_cancel(&sp->retry_timer);
794
819
  grpc_fd_shutdown(sp->emfd, GRPC_ERROR_CREATE("Server shutdown"));
795
820
  }
796
821
  }
@@ -30,6 +30,7 @@
30
30
  #include "src/core/lib/iomgr/resolve_address.h"
31
31
  #include "src/core/lib/iomgr/socket_utils_posix.h"
32
32
  #include "src/core/lib/iomgr/tcp_server.h"
33
+ #include "src/core/lib/iomgr/timer.h"
33
34
  #include "src/core/lib/resource_quota/memory_quota.h"
34
35
 
35
36
  // one listening port
@@ -52,6 +53,11 @@ typedef struct grpc_tcp_listener {
52
53
  // identified while iterating through 'next'.
53
54
  struct grpc_tcp_listener* sibling;
54
55
  int is_sibling;
56
+ // If an accept4() call fails, a timer is started to drain the accept queue in
57
+ // case no further connection attempts reach the gRPC server.
58
+ grpc_closure retry_closure;
59
+ grpc_timer retry_timer;
60
+ gpr_atm retry_timer_armed;
55
61
  } grpc_tcp_listener;
56
62
 
57
63
  // the overall server
@@ -139,4 +145,10 @@ grpc_error_handle grpc_tcp_server_prepare_socket(
139
145
  // Ruturn true if the platform supports ifaddrs
140
146
  bool grpc_tcp_server_have_ifaddrs(void);
141
147
 
148
+ // Initialize (but don't start) the timer and callback to retry accept4() on a
149
+ // listening socket after file descriptors have been exhausted. This must be
150
+ // called when creating a new listener.
151
+ void grpc_tcp_server_listener_initialize_retry_timer(
152
+ grpc_tcp_listener* listener);
153
+
142
154
  #endif // GRPC_SRC_CORE_LIB_IOMGR_TCP_SERVER_UTILS_POSIX_H
@@ -18,6 +18,8 @@
18
18
 
19
19
  #include <grpc/support/port_platform.h>
20
20
 
21
+ #include <grpc/support/atm.h>
22
+
21
23
  #include "src/core/lib/iomgr/port.h"
22
24
 
23
25
  #ifdef GRPC_POSIX_SOCKET_TCP_SERVER_UTILS_COMMON
@@ -81,6 +83,24 @@ static int get_max_accept_queue_size(void) {
81
83
  return s_max_accept_queue_size;
82
84
  }
83
85
 
86
+ static void listener_retry_timer_cb(void* arg, grpc_error_handle err) {
87
+ // Do nothing if cancelled.
88
+ if (!err.ok()) return;
89
+ grpc_tcp_listener* listener = static_cast<grpc_tcp_listener*>(arg);
90
+ gpr_atm_no_barrier_store(&listener->retry_timer_armed, false);
91
+ if (!grpc_fd_is_shutdown(listener->emfd)) {
92
+ grpc_fd_set_readable(listener->emfd);
93
+ }
94
+ }
95
+
96
+ void grpc_tcp_server_listener_initialize_retry_timer(
97
+ grpc_tcp_listener* listener) {
98
+ gpr_atm_no_barrier_store(&listener->retry_timer_armed, false);
99
+ grpc_timer_init_unset(&listener->retry_timer);
100
+ GRPC_CLOSURE_INIT(&listener->retry_closure, listener_retry_timer_cb, listener,
101
+ grpc_schedule_on_exec_ctx);
102
+ }
103
+
84
104
  static grpc_error_handle add_socket_to_server(grpc_tcp_server* s, int fd,
85
105
  const grpc_resolved_address* addr,
86
106
  unsigned port_index,
@@ -112,6 +132,7 @@ static grpc_error_handle add_socket_to_server(grpc_tcp_server* s, int fd,
112
132
  sp->server = s;
113
133
  sp->fd = fd;
114
134
  sp->emfd = grpc_fd_create(fd, name.c_str(), true);
135
+ grpc_tcp_server_listener_initialize_retry_timer(sp);
115
136
 
116
137
  // Check and set fd as prellocated
117
138
  if (grpc_tcp_server_pre_allocated_fd(s) == fd) {
@@ -14,5 +14,5 @@
14
14
 
15
15
  # GRPC contains the General RPC module.
16
16
  module GRPC
17
- VERSION = '1.53.1'
17
+ VERSION = '1.53.2'
18
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.53.1
4
+ version: 1.53.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - gRPC Authors
8
8
  autorequire:
9
9
  bindir: src/ruby/bin
10
10
  cert_chain: []
11
- date: 2023-05-11 00:00:00.000000000 Z
11
+ date: 2023-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -3060,7 +3060,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
3060
3060
  - !ruby/object:Gem::Version
3061
3061
  version: '0'
3062
3062
  requirements: []
3063
- rubygems_version: 3.4.13
3063
+ rubygems_version: 3.4.17
3064
3064
  signing_key:
3065
3065
  specification_version: 4
3066
3066
  summary: GRPC system in Ruby