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 +4 -4
- data/Makefile +2 -2
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +1 -0
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +29 -0
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener.h +3 -0
- data/src/core/lib/iomgr/tcp_server_posix.cc +39 -14
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +12 -0
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +21 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c237088f6035b2dc6f188374ab0531f3f3b8307f61fdc5b8a57518bc02b222c
|
4
|
+
data.tar.gz: fb1aec781fd0bf129d3740eeed7fa432b0412f29ba4ec2da79b197bb903cb1bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
415
|
-
CSHARP_VERSION = 2.53.
|
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
|
-
}
|
354
|
-
|
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
|
-
|
359
|
-
|
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) {
|
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.
|
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-
|
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.
|
3063
|
+
rubygems_version: 3.4.17
|
3064
3064
|
signing_key:
|
3065
3065
|
specification_version: 4
|
3066
3066
|
summary: GRPC system in Ruby
|