grpc 1.54.2 → 1.54.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d598caa30453ae27a2e770adab7de9eae672d3ce5a1f90424251b4242493800
4
- data.tar.gz: c050771539ec9df8569b590297783ee9a0538ff692b6d45a1cf1b0fdb73a0120
3
+ metadata.gz: d711d99d6ff118f1995857a501d43285a4949c571c4a15dc9c01214f83b5e5f9
4
+ data.tar.gz: af50cfde4b585decdb3eff98182c02bc0f1f77beeb2ea282de75d785df0b5ca4
5
5
  SHA512:
6
- metadata.gz: e469fa1123d56a78b3ec61d32ad3a4c89086f3fb0dded22e51c64d68da0cce5d9d42742a123cafee1c2c3e6ebafa0a322d81d88e82498f20454e0f9eb3e65275
7
- data.tar.gz: 38435b040d5ec1a61fa39caef97bc45229a17b2f1a3313588d1108b0f3e039cead9ffeb5421b2c2c0c4cd856940ac6b0ab852f694f480d8449874dfb3e246399
6
+ metadata.gz: 30c5de74b5a8d4cb6747799863e0189f31406b5dc247dd8321aa724eeda3c2429c59cf0f9103fd64a54481d474e7b639a162cecc0eb20eaa1d671f887b50ff5e
7
+ data.tar.gz: 45076a87b0b33bd3ee672e59dc7a3904b44f2db416ec2f3f58e170a1f1c5dc6588199a1a37fbba617f6f616b39eec7c880268f20b0489aa2f9674baaca53a999
data/Makefile CHANGED
@@ -411,8 +411,8 @@ Q = @
411
411
  endif
412
412
 
413
413
  CORE_VERSION = 31.0.0
414
- CPP_VERSION = 1.54.2
415
- CSHARP_VERSION = 2.54.2
414
+ CPP_VERSION = 1.54.3
415
+ CSHARP_VERSION = 2.54.3
416
416
 
417
417
  CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
418
418
  CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -3037,6 +3037,8 @@ void ClientChannel::FilterBasedLoadBalancedCall::RecvInitialMetadataReady(
3037
3037
  // recv_initial_metadata_flags is not populated for clients
3038
3038
  self->call_attempt_tracer()->RecordReceivedInitialMetadata(
3039
3039
  self->recv_initial_metadata_);
3040
+ auto* peer_string = self->recv_initial_metadata_->get_pointer(PeerString());
3041
+ if (peer_string != nullptr) self->peer_string_ = peer_string->Ref();
3040
3042
  }
3041
3043
  Closure::Run(DEBUG_LOCATION, self->original_recv_initial_metadata_ready_,
3042
3044
  error);
@@ -3080,12 +3082,8 @@ void ClientChannel::FilterBasedLoadBalancedCall::RecvTrailingMetadataReady(
3080
3082
  }
3081
3083
  }
3082
3084
  absl::string_view peer_string;
3083
- if (self->recv_initial_metadata_ != nullptr) {
3084
- Slice* peer_string_slice =
3085
- self->recv_initial_metadata_->get_pointer(PeerString());
3086
- if (peer_string_slice != nullptr) {
3087
- peer_string = peer_string_slice->as_string_view();
3088
- }
3085
+ if (self->peer_string_.has_value()) {
3086
+ peer_string = self->peer_string_->as_string_view();
3089
3087
  }
3090
3088
  self->RecordCallCompletion(status, self->recv_trailing_metadata_,
3091
3089
  self->transport_stream_stats_, peer_string);
@@ -63,6 +63,7 @@
63
63
  #include "src/core/lib/resolver/resolver.h"
64
64
  #include "src/core/lib/resource_quota/arena.h"
65
65
  #include "src/core/lib/service_config/service_config.h"
66
+ #include "src/core/lib/slice/slice.h"
66
67
  #include "src/core/lib/surface/channel.h"
67
68
  #include "src/core/lib/transport/connectivity_state.h"
68
69
  #include "src/core/lib/transport/metadata_batch.h"
@@ -548,6 +549,7 @@ class ClientChannel::FilterBasedLoadBalancedCall
548
549
  CallCombiner* call_combiner_;
549
550
  grpc_polling_entity* pollent_;
550
551
  grpc_closure* on_call_destruction_complete_;
552
+ absl::optional<Slice> peer_string_;
551
553
 
552
554
  // Set when we get a cancel_stream op.
553
555
  grpc_error_handle cancel_error_;
@@ -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 {
@@ -136,6 +139,32 @@ void PosixEngineListenerImpl::AsyncConnectionAcceptor::NotifyOnAccept(
136
139
  switch (errno) {
137
140
  case EINTR:
138
141
  continue;
142
+ case EMFILE:
143
+ // When the process runs out of fds, accept4() returns EMFILE. When
144
+ // this happens, the connection is left in the accept queue until
145
+ // either a read event triggers the on_read callback, or time has
146
+ // passed and the accept should be re-tried regardless. This callback
147
+ // is not cancelled, so a spurious wakeup may occur even when there's
148
+ // nothing to accept. This is not a performant code path, but if an fd
149
+ // limit has been reached, the system is likely in an unhappy state
150
+ // regardless.
151
+ GRPC_LOG_EVERY_N_SEC(1, GPR_ERROR, "%s",
152
+ "File descriptor limit reached. Retrying.");
153
+ handle_->NotifyOnRead(notify_on_accept_);
154
+ // Do not schedule another timer if one is already armed.
155
+ if (retry_timer_armed_.exchange(true)) return;
156
+ // Hold a ref while the retry timer is waiting, to prevent listener
157
+ // destruction and the races that would ensue.
158
+ Ref();
159
+ std::ignore =
160
+ engine_->RunAfter(grpc_core::Duration::Seconds(1), [this]() {
161
+ retry_timer_armed_.store(false);
162
+ if (!handle_->IsHandleShutdown()) {
163
+ handle_->SetReadable();
164
+ }
165
+ Unref();
166
+ });
167
+ return;
139
168
  case EAGAIN:
140
169
  case ECONNABORTED:
141
170
  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>
@@ -75,6 +80,8 @@
75
80
  #include "src/core/lib/transport/error_utils.h"
76
81
 
77
82
  static std::atomic<int64_t> num_dropped_connections{0};
83
+ static constexpr grpc_core::Duration kRetryAcceptWaitTime{
84
+ grpc_core::Duration::Seconds(1)};
78
85
 
79
86
  using ::grpc_event_engine::experimental::EndpointConfig;
80
87
  using ::grpc_event_engine::experimental::EventEngine;
@@ -339,22 +346,38 @@ static void on_read(void* arg, grpc_error_handle err) {
339
346
  if (fd < 0) {
340
347
  if (errno == EINTR) {
341
348
  continue;
342
- } else if (errno == EAGAIN || errno == ECONNABORTED ||
343
- errno == EWOULDBLOCK) {
349
+ }
350
+ // When the process runs out of fds, accept4() returns EMFILE. When this
351
+ // happens, the connection is left in the accept queue until either a
352
+ // read event triggers the on_read callback, or time has passed and the
353
+ // accept should be re-tried regardless. This callback is not cancelled,
354
+ // so a spurious wakeup may occur even when there's nothing to accept.
355
+ // This is not a performant code path, but if an fd limit has been
356
+ // reached, the system is likely in an unhappy state regardless.
357
+ if (errno == EMFILE) {
358
+ GRPC_LOG_EVERY_N_SEC(1, GPR_ERROR, "%s",
359
+ "File descriptor limit reached. Retrying.");
360
+ grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
361
+ if (gpr_atm_full_xchg(&sp->retry_timer_armed, true)) return;
362
+ grpc_timer_init(&sp->retry_timer,
363
+ grpc_core::Timestamp::Now() + kRetryAcceptWaitTime,
364
+ &sp->retry_closure);
365
+ return;
366
+ }
367
+ if (errno == EAGAIN || errno == ECONNABORTED || errno == EWOULDBLOCK) {
344
368
  grpc_fd_notify_on_read(sp->emfd, &sp->read_closure);
345
369
  return;
370
+ }
371
+ gpr_mu_lock(&sp->server->mu);
372
+ if (!sp->server->shutdown_listeners) {
373
+ gpr_log(GPR_ERROR, "Failed accept4: %s",
374
+ grpc_core::StrError(errno).c_str());
346
375
  } else {
347
- gpr_mu_lock(&sp->server->mu);
348
- if (!sp->server->shutdown_listeners) {
349
- gpr_log(GPR_ERROR, "Failed accept4: %s",
350
- grpc_core::StrError(errno).c_str());
351
- } else {
352
- // if we have shutdown listeners, accept4 could fail, and we
353
- // needn't notify users
354
- }
355
- gpr_mu_unlock(&sp->server->mu);
356
- goto error;
376
+ // if we have shutdown listeners, accept4 could fail, and we
377
+ // needn't notify users
357
378
  }
379
+ gpr_mu_unlock(&sp->server->mu);
380
+ goto error;
358
381
  }
359
382
 
360
383
  if (sp->server->memory_quota->IsMemoryPressureHigh()) {
@@ -547,6 +570,7 @@ static grpc_error_handle clone_port(grpc_tcp_listener* listener,
547
570
  sp->port_index = listener->port_index;
548
571
  sp->fd_index = listener->fd_index + count - i;
549
572
  GPR_ASSERT(sp->emfd);
573
+ grpc_tcp_server_listener_initialize_retry_timer(sp);
550
574
  while (listener->server->tail->next != nullptr) {
551
575
  listener->server->tail = listener->server->tail->next;
552
576
  }
@@ -780,6 +804,7 @@ static void tcp_server_shutdown_listeners(grpc_tcp_server* s) {
780
804
  if (s->active_ports) {
781
805
  grpc_tcp_listener* sp;
782
806
  for (sp = s->head; sp; sp = sp->next) {
807
+ grpc_timer_cancel(&sp->retry_timer);
783
808
  grpc_fd_shutdown(sp->emfd, GRPC_ERROR_CREATE("Server shutdown"));
784
809
  }
785
810
  }
@@ -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.54.2'
17
+ VERSION = '1.54.3'
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.54.2
4
+ version: 1.54.3
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-09 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
@@ -3093,7 +3093,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
3093
3093
  - !ruby/object:Gem::Version
3094
3094
  version: '0'
3095
3095
  requirements: []
3096
- rubygems_version: 3.4.12
3096
+ rubygems_version: 3.4.17
3097
3097
  signing_key:
3098
3098
  specification_version: 4
3099
3099
  summary: GRPC system in Ruby