From 48773405dd0468ce8a5dca921f0df0360acb80bc Mon Sep 17 00:00:00 2001 From: prettyboy Date: Thu, 14 Feb 2019 20:57:35 +0300 Subject: [PATCH 001/112] Pass WSA_FLAG_NO_HANDLE_INHERIT flags to the WSASocketA() to avoid handle leaking on the Windows in case of using CreateProcess() on the server --- src/core/lib/iomgr/tcp_server_windows.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index b01afdcc9db..67e4f33d44d 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -255,7 +255,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,7 +493,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; From 76e9d1add7555378c204eb0475e9b4ac1c8f2816 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Thu, 21 Feb 2019 19:20:34 +0300 Subject: [PATCH 002/112] Set WSA_FLAG_NO_HANDLE_INHERIT flag wherever the WSASocket is used. Check WSA_FLAG_NO_HANDLE_INHERIT is supported. --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 2 +- src/core/lib/iomgr/endpoint_pair_windows.cc | 8 +++---- src/core/lib/iomgr/socket_windows.cc | 21 +++++++++++++++++++ src/core/lib/iomgr/socket_windows.h | 9 ++++++++ src/core/lib/iomgr/tcp_client_windows.cc | 4 ++-- src/core/lib/iomgr/tcp_server_windows.cc | 4 ++-- test/cpp/naming/resolver_component_test.cc | 4 ++-- 7 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 02121aa0ab4..dedc77aae97 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -442,7 +442,7 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = WSASocket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED); + SOCKET s = grpc_create_wsa_socket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index 177331d6812..842a4ff877b 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -40,8 +40,8 @@ static void create_sockets(SOCKET sv[2]) { SOCKADDR_IN addr; int addr_len = sizeof(addr); - lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + lst_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -53,8 +53,8 @@ static void create_sockets(SOCKET sv[2]) { GPR_ASSERT(getsockname(lst_sock, (grpc_sockaddr*)&addr, &addr_len) != SOCKET_ERROR); - cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + cli_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 999c6646ad4..19013c76b3e 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -181,4 +181,25 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } +SOCKET grpc_create_wsa_socket(int family, + int type, + int protocol, + LPWSAPROTOCOL_INFOA protocol_info, + GROUP group, + DWORD flags) { + bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; + if (!g_is_wsa_no_handle_inherit_supported && is_wsa_no_handle_inherit_set) { + flags ^= WSA_FLAG_NO_HANDLE_INHERIT; + } + SOCKET sock = WSASocket(family, type, protocol, protocol_info, group, flags); + /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see + https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx + for details. */ + if (sock == INVALID_SOCKET && is_wsa_no_handle_inherit_set) { + g_is_wsa_no_handle_inherit_supported = false; + sock = WSASocket(family, type, protocol, protocol_info, group, flags ^ WSA_FLAG_NO_HANDLE_INHERIT); + } + return sock; +} + #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 46d7d583560..0eb8a2271f5 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -114,6 +114,15 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); +static bool g_is_wsa_no_handle_inherit_supported = true; + +SOCKET grpc_create_wsa_socket(int family, + int type, + int protocol, + LPWSAPROTOCOL_INFOA protocol_info, + GROUP group, + DWORD flags); + #endif #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index e5b5502597e..881f7670610 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -147,8 +147,8 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, addr = &addr6_v4mapped; } - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED); + sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 67e4f33d44d..9c398ebc8a5 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -254,7 +254,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { return GRPC_ERROR_NONE; } - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); @@ -492,7 +492,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 9532529e45d..072504f4e38 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,8 +279,8 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, - WSA_FLAG_OVERLAPPED); + SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 39f562e2b78c4b0dfc68f4f7aadafcc0d20b76dd Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Thu, 21 Feb 2019 19:27:09 +0300 Subject: [PATCH 003/112] Define WSA_FLAG_NO_HANDLE_INHERIT if it's not defined --- src/core/lib/iomgr/socket_windows.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 0eb8a2271f5..25b347d1efa 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -32,6 +32,10 @@ #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/iomgr_internal.h" +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + /* This holds the data for an outstanding read or write on a socket. The mutex to protect the concurrent access to that data is the one inside the winsocket wrapper. */ From b74044a67d2e4f911cc68395eeadf1c5f6b013fc Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Thu, 21 Feb 2019 19:47:38 +0300 Subject: [PATCH 004/112] Use LPWSAPROTOCOL_INFO instead of LPWSAPROTOCOL_INFOA --- src/core/lib/iomgr/socket_windows.cc | 2 +- src/core/lib/iomgr/socket_windows.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 19013c76b3e..7b0f43bb170 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -184,7 +184,7 @@ int grpc_ipv6_loopback_available(void) { SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFOA protocol_info, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags) { bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 25b347d1efa..987325eef71 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -123,7 +123,7 @@ static bool g_is_wsa_no_handle_inherit_supported = true; SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFOA protocol_info, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags); From bc7203e37156410b8cf2341013a36fc3f33c5ee7 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Mon, 25 Feb 2019 12:19:41 +0300 Subject: [PATCH 005/112] Fixed style --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 4 +++- src/core/lib/iomgr/endpoint_pair_windows.cc | 10 ++++++---- src/core/lib/iomgr/socket_windows.cc | 13 ++++++------- src/core/lib/iomgr/socket_windows.h | 7 ++----- src/core/lib/iomgr/tcp_client_windows.cc | 5 +++-- src/core/lib/iomgr/tcp_server_windows.cc | 10 ++++++---- test/cpp/naming/resolver_component_test.cc | 5 +++-- 7 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index dedc77aae97..5d77fb761f3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -442,7 +442,9 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = grpc_create_wsa_socket(af, type, protocol, nullptr, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = grpc_create_wsa_socket( + af, type, protocol, nullptr, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index 842a4ff877b..b914e1c6660 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -40,8 +40,9 @@ static void create_sockets(SOCKET sv[2]) { SOCKADDR_IN addr; int addr_len = sizeof(addr); - lst_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + lst_sock = + grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -53,8 +54,9 @@ static void create_sockets(SOCKET sv[2]) { GPR_ASSERT(getsockname(lst_sock, (grpc_sockaddr*)&addr, &addr_len) != SOCKET_ERROR); - cli_sock = grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + cli_sock = + grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 7b0f43bb170..f55fe674f15 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -181,23 +181,22 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } -SOCKET grpc_create_wsa_socket(int family, - int type, - int protocol, - LPWSAPROTOCOL_INFO protocol_info, - GROUP group, +SOCKET grpc_create_wsa_socket(int family, int type, int protocol, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags) { bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; if (!g_is_wsa_no_handle_inherit_supported && is_wsa_no_handle_inherit_set) { flags ^= WSA_FLAG_NO_HANDLE_INHERIT; } SOCKET sock = WSASocket(family, type, protocol, protocol_info, group, flags); - /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see + /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows + versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ if (sock == INVALID_SOCKET && is_wsa_no_handle_inherit_set) { g_is_wsa_no_handle_inherit_supported = false; - sock = WSASocket(family, type, protocol, protocol_info, group, flags ^ WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(family, type, protocol, protocol_info, group, + flags ^ WSA_FLAG_NO_HANDLE_INHERIT); } return sock; } diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 987325eef71..79c5c8fbee3 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -120,11 +120,8 @@ int grpc_ipv6_loopback_available(void); static bool g_is_wsa_no_handle_inherit_supported = true; -SOCKET grpc_create_wsa_socket(int family, - int type, - int protocol, - LPWSAPROTOCOL_INFO protocol_info, - GROUP group, +SOCKET grpc_create_wsa_socket(int family, int type, int protocol, + LPWSAPROTOCOL_INFO protocol_info, GROUP group, DWORD flags); #endif diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 881f7670610..5b15ee2c4e6 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -147,8 +147,9 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, addr = &addr6_v4mapped; } - sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = + grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 9c398ebc8a5..db4bb84092b 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -254,8 +254,9 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { return GRPC_ERROR_NONE; } - sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = + grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -492,8 +493,9 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - sock = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = + grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 072504f4e38..43a9a066266 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,8 +279,9 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = grpc_create_wsa_socket( + AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 0b96d0f71103023b15940893c3f249f36f2d9595 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 12:13:18 +0300 Subject: [PATCH 006/112] Check once that WSA_FLAG_NO_HANDLE_INHERIT is supported --- .../dns/c_ares/grpc_ares_ev_driver_windows.cc | 4 +--- src/core/lib/iomgr/endpoint_pair_windows.cc | 10 ++++----- src/core/lib/iomgr/iomgr_windows.cc | 1 + src/core/lib/iomgr/socket_windows.cc | 21 +++++++------------ src/core/lib/iomgr/socket_windows.h | 6 ++---- src/core/lib/iomgr/tcp_client_windows.cc | 5 ++--- src/core/lib/iomgr/tcp_server_windows.cc | 10 ++++----- 7 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 5d77fb761f3..5cd988ec1d7 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -442,9 +442,7 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = grpc_create_wsa_socket( - af, type, protocol, nullptr, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = WSASocket(af, type, protocol, nullptr, 0, grpc_wsa_socket_flags); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index b914e1c6660..ee6a617f61f 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -40,9 +40,8 @@ static void create_sockets(SOCKET sv[2]) { SOCKADDR_IN addr; int addr_len = sizeof(addr); - lst_sock = - grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -54,9 +53,8 @@ static void create_sockets(SOCKET sv[2]) { GPR_ASSERT(getsockname(lst_sock, (grpc_sockaddr*)&addr, &addr_len) != SOCKET_ERROR); - cli_sock = - grpc_create_wsa_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc index e517a6caee4..0e897dafb16 100644 --- a/src/core/lib/iomgr/iomgr_windows.cc +++ b/src/core/lib/iomgr/iomgr_windows.cc @@ -61,6 +61,7 @@ static void iomgr_platform_init(void) { winsock_init(); grpc_iocp_init(); grpc_pollset_global_init(); + grpc_wsa_socket_flags_init(); } static void iomgr_platform_flush(void) { grpc_iocp_flush(); } diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index f55fe674f15..9e5c579c60d 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -181,24 +181,19 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } -SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFO protocol_info, GROUP group, - DWORD flags) { - bool is_wsa_no_handle_inherit_set = flags & WSA_FLAG_NO_HANDLE_INHERIT; - if (!g_is_wsa_no_handle_inherit_supported && is_wsa_no_handle_inherit_set) { - flags ^= WSA_FLAG_NO_HANDLE_INHERIT; - } - SOCKET sock = WSASocket(family, type, protocol, protocol_info, group, flags); +void grpc_wsa_socket_flags_init() { + grpc_wsa_socket_flags = WSA_FLAG_OVERLAPPED; /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ - if (sock == INVALID_SOCKET && is_wsa_no_handle_inherit_set) { - g_is_wsa_no_handle_inherit_supported = false; - sock = WSASocket(family, type, protocol, protocol_info, group, - flags ^ WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, NULL, + grpc_wsa_socket_flags & WSA_FLAG_NO_HANDLE_INHERIT); + if (sock != INVALID_SOCKET) { + /* Windows 7, Windows 2008 R2 with SP1 or later */ + grpc_wsa_socket_flags &= WSA_FLAG_NO_HANDLE_INHERIT; + closesocket(sock); } - return sock; } #endif /* GRPC_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 79c5c8fbee3..0cf70f39a10 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -118,11 +118,9 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); -static bool g_is_wsa_no_handle_inherit_supported = true; +static DWORD grpc_wsa_socket_flags = 0; -SOCKET grpc_create_wsa_socket(int family, int type, int protocol, - LPWSAPROTOCOL_INFO protocol_info, GROUP group, - DWORD flags); +void grpc_wsa_socket_flags_init(); #endif diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 5b15ee2c4e6..147edf4ffe4 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -147,9 +147,8 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, addr = &addr6_v4mapped; } - sock = - grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index db4bb84092b..5e0217a5d36 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -254,9 +254,8 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { return GRPC_ERROR_NONE; } - sock = - grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,9 +492,8 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, addr = &wildcard; } - sock = - grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, + grpc_wsa_socket_flags); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; From 7d1e2015395922ea8d62740466eb95c10483e0ac Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 12:16:53 +0300 Subject: [PATCH 007/112] Use grpc_wsa_socket_flags in the test/cpp/naming/resolver_component_test.cc --- test/cpp/naming/resolver_component_test.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 43a9a066266..7410a0e6597 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,9 +279,8 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = grpc_create_wsa_socket( - AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, + nullptr, 0, grpc_wsa_socket_flags); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 8232d698207899d656ace9a27edf921a441db82b Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 12:32:55 +0300 Subject: [PATCH 008/112] Reverted changes in the test/cpp/naming/resolver_component_test.cc --- test/cpp/naming/resolver_component_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 7410a0e6597..9532529e45d 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -279,8 +279,8 @@ void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) { } std::vector sockets; for (size_t i = 0; i < 50; i++) { - SOCKET s = grpc_create_wsa_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, - nullptr, 0, grpc_wsa_socket_flags); + SOCKET s = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0, + WSA_FLAG_OVERLAPPED); ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL) << "Failed to create TCP ipv6 socket"; gpr_log(GPR_DEBUG, "Opened socket: %d", s); From 6e07d04c928ea1b23742a0662cceabef5a1ae107 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 13:48:28 +0300 Subject: [PATCH 009/112] Fixed silly error --- src/core/lib/iomgr/socket_windows.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 9e5c579c60d..1794b162223 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -188,10 +188,10 @@ void grpc_wsa_socket_flags_init() { https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, NULL, - grpc_wsa_socket_flags & WSA_FLAG_NO_HANDLE_INHERIT); + grpc_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); if (sock != INVALID_SOCKET) { /* Windows 7, Windows 2008 R2 with SP1 or later */ - grpc_wsa_socket_flags &= WSA_FLAG_NO_HANDLE_INHERIT; + grpc_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; closesocket(sock); } } From 6698cf87b389420794390ca7d5c3327f06cbf1aa Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 26 Feb 2019 15:41:11 +0300 Subject: [PATCH 010/112] Single instances of the grpc_wsa_socket_flags --- src/core/lib/iomgr/socket_windows.cc | 2 ++ src/core/lib/iomgr/socket_windows.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 1794b162223..9b9b745829e 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -39,6 +39,8 @@ #include "src/core/lib/iomgr/sockaddr_windows.h" #include "src/core/lib/iomgr/socket_windows.h" +DWORD grpc_wsa_socket_flags; + grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name) { char* final_name; grpc_winsocket* r = (grpc_winsocket*)gpr_malloc(sizeof(grpc_winsocket)); diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 0cf70f39a10..9a5caef9f52 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -118,7 +118,7 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); -static DWORD grpc_wsa_socket_flags = 0; +extern DWORD grpc_wsa_socket_flags; void grpc_wsa_socket_flags_init(); From b3254101418d2c733380f532a0e80da6e3042194 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Tue, 12 Mar 2019 18:17:09 +0300 Subject: [PATCH 011/112] Added grpc_get_default_wsa_socket_flags() --- .../resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc | 3 ++- src/core/lib/iomgr/endpoint_pair_windows.cc | 4 ++-- src/core/lib/iomgr/socket_windows.cc | 4 +++- src/core/lib/iomgr/socket_windows.h | 2 ++ src/core/lib/iomgr/tcp_client_windows.cc | 2 +- src/core/lib/iomgr/tcp_server_windows.cc | 4 ++-- 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc index 5cd988ec1d7..69a206ba847 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc @@ -442,7 +442,8 @@ class SockToPolledFdMap { */ static ares_socket_t Socket(int af, int type, int protocol, void* user_data) { SockToPolledFdMap* map = static_cast(user_data); - SOCKET s = WSASocket(af, type, protocol, nullptr, 0, grpc_wsa_socket_flags); + SOCKET s = WSASocket(af, type, protocol, nullptr, 0, + grpc_get_default_wsa_socket_flags()); if (s == INVALID_SOCKET) { return s; } diff --git a/src/core/lib/iomgr/endpoint_pair_windows.cc b/src/core/lib/iomgr/endpoint_pair_windows.cc index ee6a617f61f..9962809a27b 100644 --- a/src/core/lib/iomgr/endpoint_pair_windows.cc +++ b/src/core/lib/iomgr/endpoint_pair_windows.cc @@ -41,7 +41,7 @@ static void create_sockets(SOCKET sv[2]) { int addr_len = sizeof(addr); lst_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); GPR_ASSERT(lst_sock != INVALID_SOCKET); memset(&addr, 0, sizeof(addr)); @@ -54,7 +54,7 @@ static void create_sockets(SOCKET sv[2]) { SOCKET_ERROR); cli_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); GPR_ASSERT(cli_sock != INVALID_SOCKET); GPR_ASSERT(WSAConnect(cli_sock, (grpc_sockaddr*)&addr, addr_len, NULL, NULL, diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 9b9b745829e..2026c95062f 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -183,13 +183,15 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } +DWORD grpc_get_default_wsa_socket_flags() { return grpc_wsa_socket_flags; } + void grpc_wsa_socket_flags_init() { grpc_wsa_socket_flags = WSA_FLAG_OVERLAPPED; /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ - SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, NULL, + SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, grpc_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); if (sock != INVALID_SOCKET) { /* Windows 7, Windows 2008 R2 with SP1 or later */ diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 9a5caef9f52..32b88880569 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -122,6 +122,8 @@ extern DWORD grpc_wsa_socket_flags; void grpc_wsa_socket_flags_init(); +DWORD grpc_get_default_wsa_socket_flags(); + #endif #endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/lib/iomgr/tcp_client_windows.cc b/src/core/lib/iomgr/tcp_client_windows.cc index 147edf4ffe4..264af452618 100644 --- a/src/core/lib/iomgr/tcp_client_windows.cc +++ b/src/core/lib/iomgr/tcp_client_windows.cc @@ -148,7 +148,7 @@ static void tcp_connect(grpc_closure* on_done, grpc_endpoint** endpoint, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; diff --git a/src/core/lib/iomgr/tcp_server_windows.cc b/src/core/lib/iomgr/tcp_server_windows.cc index 5e0217a5d36..7ac423440e2 100644 --- a/src/core/lib/iomgr/tcp_server_windows.cc +++ b/src/core/lib/iomgr/tcp_server_windows.cc @@ -255,7 +255,7 @@ static grpc_error* start_accept_locked(grpc_tcp_listener* port) { } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto failure; @@ -493,7 +493,7 @@ static grpc_error* tcp_server_add_port(grpc_tcp_server* s, } sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags); + grpc_get_default_wsa_socket_flags()); if (sock == INVALID_SOCKET) { error = GRPC_WSA_ERROR(WSAGetLastError(), "WSASocket"); goto done; From c792aae3286454a0fd035dc8f8d79da02c2a9a63 Mon Sep 17 00:00:00 2001 From: frazenshtein Date: Wed, 13 Mar 2019 10:29:41 +0300 Subject: [PATCH 012/112] Removed grpc_wsa_socket_flags variable from the header, renamed to s_wsa_socket_flags --- src/core/lib/iomgr/socket_windows.cc | 10 +++++----- src/core/lib/iomgr/socket_windows.h | 2 -- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc index 2026c95062f..c87cfa8e831 100644 --- a/src/core/lib/iomgr/socket_windows.cc +++ b/src/core/lib/iomgr/socket_windows.cc @@ -39,7 +39,7 @@ #include "src/core/lib/iomgr/sockaddr_windows.h" #include "src/core/lib/iomgr/socket_windows.h" -DWORD grpc_wsa_socket_flags; +static DWORD s_wsa_socket_flags; grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name) { char* final_name; @@ -183,19 +183,19 @@ int grpc_ipv6_loopback_available(void) { return g_ipv6_loopback_available; } -DWORD grpc_get_default_wsa_socket_flags() { return grpc_wsa_socket_flags; } +DWORD grpc_get_default_wsa_socket_flags() { return s_wsa_socket_flags; } void grpc_wsa_socket_flags_init() { - grpc_wsa_socket_flags = WSA_FLAG_OVERLAPPED; + s_wsa_socket_flags = WSA_FLAG_OVERLAPPED; /* WSA_FLAG_NO_HANDLE_INHERIT may be not supported on the older Windows versions, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx for details. */ SOCKET sock = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, - grpc_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); + s_wsa_socket_flags | WSA_FLAG_NO_HANDLE_INHERIT); if (sock != INVALID_SOCKET) { /* Windows 7, Windows 2008 R2 with SP1 or later */ - grpc_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; + s_wsa_socket_flags |= WSA_FLAG_NO_HANDLE_INHERIT; closesocket(sock); } } diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h index 32b88880569..5fed6909e6f 100644 --- a/src/core/lib/iomgr/socket_windows.h +++ b/src/core/lib/iomgr/socket_windows.h @@ -118,8 +118,6 @@ void grpc_socket_become_ready(grpc_winsocket* winsocket, The value is probed once, and cached for the life of the process. */ int grpc_ipv6_loopback_available(void); -extern DWORD grpc_wsa_socket_flags; - void grpc_wsa_socket_flags_init(); DWORD grpc_get_default_wsa_socket_flags(); From 6da0ca442142855bc2cacdeed4ed307b5650dbea Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 20 Mar 2019 10:38:03 -0700 Subject: [PATCH 013/112] Bring ChannelArguments to grpc_impl from grpc --- BUILD | 1 + include/grpcpp/impl/server_builder_plugin.h | 7 +- include/grpcpp/security/credentials.h | 2 +- include/grpcpp/support/channel_arguments.h | 122 +------------- .../grpcpp/support/channel_arguments_impl.h | 152 ++++++++++++++++++ src/cpp/client/create_channel.cc | 1 - src/cpp/common/channel_arguments.cc | 6 +- src/cpp/common/secure_channel_arguments.cc | 4 +- 8 files changed, 166 insertions(+), 129 deletions(-) create mode 100644 include/grpcpp/support/channel_arguments_impl.h diff --git a/BUILD b/BUILD index 9e052dcf0c2..3a16d6cc921 100644 --- a/BUILD +++ b/BUILD @@ -253,6 +253,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 39450b42d56..a6d8902970f 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -23,11 +23,14 @@ #include +namespace grpc_impl { + +class ChannelArguments; +} // namespace grpc_impl namespace grpc { class ServerBuilder; class ServerInitializer; -class ChannelArguments; /// This interface is meant for internal usage only. Implementations of this /// interface should add themselves to a \a ServerBuilder instance through the @@ -55,7 +58,7 @@ class ServerBuilderPlugin { /// UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(), /// before the Server instance is created. - virtual void UpdateChannelArguments(ChannelArguments* args) {} + virtual void UpdateChannelArguments(grpc_impl::ChannelArguments* args) {} virtual bool has_sync_methods() const { return false; } virtual bool has_async_methods() const { return false; } diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index dfea3900048..0fe4e9faa88 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -27,13 +27,13 @@ #include #include #include +#include #include #include struct grpc_call; namespace grpc { -class ChannelArguments; class Channel; class SecureChannelCredentials; class CallCredentials; diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 217929d4aca..46e0180cb11 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -19,129 +19,11 @@ #ifndef GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H #define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_H -#include -#include - -#include -#include -#include +#include namespace grpc { -namespace testing { -class ChannelArgumentsTest; -} // namespace testing - -class ResourceQuota; - -/// Options for channel creation. The user can use generic setters to pass -/// key value pairs down to C channel creation code. For gRPC related options, -/// concrete setters are provided. -class ChannelArguments { - public: - ChannelArguments(); - ~ChannelArguments(); - - ChannelArguments(const ChannelArguments& other); - ChannelArguments& operator=(ChannelArguments other) { - Swap(other); - return *this; - } - - void Swap(ChannelArguments& other); - - /// Dump arguments in this instance to \a channel_args. Does not take - /// ownership of \a channel_args. - /// - /// Note that the underlying arguments are shared. Changes made to either \a - /// channel_args or this instance would be reflected on both. - void SetChannelArgs(grpc_channel_args* channel_args) const; - - // gRPC specific channel argument setters - /// Set target name override for SSL host name checking. This option is for - /// testing only and should never be used in production. - void SetSslTargetNameOverride(const grpc::string& name); - // TODO(yangg) add flow control options - /// Set the compression algorithm for the channel. - void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); - - /// Set the grpclb fallback timeout (in ms) for the channel. If this amount - /// of time has passed but we have not gotten any non-empty \a serverlist from - /// the balancer, we will fall back to use the backend address(es) returned by - /// the resolver. - void SetGrpclbFallbackTimeout(int fallback_timeout); - - /// For client channel's, the socket mutator operates on - /// "channel" sockets. For server's, the socket mutator operates - /// only on "listen" sockets. - /// TODO(apolcyn): allow socket mutators to also operate - /// on server "channel" sockets, and adjust the socket mutator - /// object to be more speficic about which type of socket - /// it should operate on. - void SetSocketMutator(grpc_socket_mutator* mutator); - - /// Set the string to prepend to the user agent. - void SetUserAgentPrefix(const grpc::string& user_agent_prefix); - - /// Set the buffer pool to be attached to the constructed channel. - void SetResourceQuota(const ResourceQuota& resource_quota); - - /// Set the max receive and send message sizes. - void SetMaxReceiveMessageSize(int size); - void SetMaxSendMessageSize(int size); - - /// Set LB policy name. - /// Note that if the name resolver returns only balancer addresses, the - /// grpclb LB policy will be used, regardless of what is specified here. - void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); - - /// Set service config in JSON form. - /// Primarily meant for use in unit tests. - void SetServiceConfigJSON(const grpc::string& service_config_json); - - // Generic channel argument setters. Only for advanced use cases. - /// Set an integer argument \a value under \a key. - void SetInt(const grpc::string& key, int value); - - // Generic channel argument setter. Only for advanced use cases. - /// Set a pointer argument \a value under \a key. Owership is not transferred. - void SetPointer(const grpc::string& key, void* value); - - void SetPointerWithVtable(const grpc::string& key, void* value, - const grpc_arg_pointer_vtable* vtable); - - /// Set a textual argument \a value under \a key. - void SetString(const grpc::string& key, const grpc::string& value); - - /// Return (by value) a C \a grpc_channel_args structure which points to - /// arguments owned by this \a ChannelArguments instance - grpc_channel_args c_channel_args() const { - grpc_channel_args out; - out.num_args = args_.size(); - out.args = args_.empty() ? NULL : const_cast(&args_[0]); - return out; - } - - private: - friend class SecureChannelCredentials; - friend class testing::ChannelArgumentsTest; - - /// Default pointer argument operations. - struct PointerVtableMembers { - static void* Copy(void* in) { return in; } - static void Destroy(void* in) {} - static int Compare(void* a, void* b) { - if (a < b) return -1; - if (a > b) return 1; - return 0; - } - }; - - // Returns empty string when it is not set. - grpc::string GetSslTargetNameOverride() const; - std::vector args_; - std::list strings_; -}; +typedef ::grpc_impl::ChannelArguments ChannelArguments; } // namespace grpc diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h new file mode 100644 index 00000000000..1e1340e716d --- /dev/null +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -0,0 +1,152 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H +#define GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H + +#include +#include + +#include +#include +#include + +namespace grpc { +namespace testing { +class ChannelArgumentsTest; +} // namespace testing + +class ResourceQuota; +class SecureChannelCredentials; +} // namespace grpc + +namespace grpc_impl { + +/// Options for channel creation. The user can use generic setters to pass +/// key value pairs down to C channel creation code. For gRPC related options, +/// concrete setters are provided. +class ChannelArguments { + public: + ChannelArguments(); + ~ChannelArguments(); + + ChannelArguments(const ChannelArguments& other); + ChannelArguments& operator=(ChannelArguments other) { + Swap(other); + return *this; + } + + void Swap(ChannelArguments& other); + + /// Dump arguments in this instance to \a channel_args. Does not take + /// ownership of \a channel_args. + /// + /// Note that the underlying arguments are shared. Changes made to either \a + /// channel_args or this instance would be reflected on both. + void SetChannelArgs(grpc_channel_args* channel_args) const; + + // gRPC specific channel argument setters + /// Set target name override for SSL host name checking. This option is for + /// testing only and should never be used in production. + void SetSslTargetNameOverride(const grpc::string& name); + // TODO(yangg) add flow control options + /// Set the compression algorithm for the channel. + void SetCompressionAlgorithm(grpc_compression_algorithm algorithm); + + /// Set the grpclb fallback timeout (in ms) for the channel. If this amount + /// of time has passed but we have not gotten any non-empty \a serverlist from + /// the balancer, we will fall back to use the backend address(es) returned by + /// the resolver. + void SetGrpclbFallbackTimeout(int fallback_timeout); + + /// For client channel's, the socket mutator operates on + /// "channel" sockets. For server's, the socket mutator operates + /// only on "listen" sockets. + /// TODO(apolcyn): allow socket mutators to also operate + /// on server "channel" sockets, and adjust the socket mutator + /// object to be more speficic about which type of socket + /// it should operate on. + void SetSocketMutator(grpc_socket_mutator* mutator); + + /// Set the string to prepend to the user agent. + void SetUserAgentPrefix(const grpc::string& user_agent_prefix); + + /// Set the buffer pool to be attached to the constructed channel. + void SetResourceQuota(const grpc::ResourceQuota& resource_quota); + + /// Set the max receive and send message sizes. + void SetMaxReceiveMessageSize(int size); + void SetMaxSendMessageSize(int size); + + /// Set LB policy name. + /// Note that if the name resolver returns only balancer addresses, the + /// grpclb LB policy will be used, regardless of what is specified here. + void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); + + /// Set service config in JSON form. + /// Primarily meant for use in unit tests. + void SetServiceConfigJSON(const grpc::string& service_config_json); + + // Generic channel argument setters. Only for advanced use cases. + /// Set an integer argument \a value under \a key. + void SetInt(const grpc::string& key, int value); + + // Generic channel argument setter. Only for advanced use cases. + /// Set a pointer argument \a value under \a key. Owership is not transferred. + void SetPointer(const grpc::string& key, void* value); + + void SetPointerWithVtable(const grpc::string& key, void* value, + const grpc_arg_pointer_vtable* vtable); + + /// Set a textual argument \a value under \a key. + void SetString(const grpc::string& key, const grpc::string& value); + + /// Return (by value) a C \a grpc_channel_args structure which points to + /// arguments owned by this \a ChannelArguments instance + grpc_channel_args c_channel_args() const { + grpc_channel_args out; + out.num_args = args_.size(); + out.args = args_.empty() ? NULL : const_cast(&args_[0]); + return out; + } + + private: + friend class grpc::SecureChannelCredentials; + friend class grpc::testing::ChannelArgumentsTest; + + /// Default pointer argument operations. + struct PointerVtableMembers { + static void* Copy(void* in) { return in; } + static void Destroy(void* in) {} + static int Compare(void* a, void* b) { + if (a < b) return -1; + if (a > b) return 1; + return 0; + } + }; + + // Returns empty string when it is not set. + grpc::string GetSslTargetNameOverride() const; + + std::vector args_; + std::list strings_; +}; + +} // namespace grpc_impl + +#endif // GRPCPP_SUPPORT_CHANNEL_ARGUMENTS_IMPL_H diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 457daa674c7..3d8e83937eb 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -26,7 +26,6 @@ #include "src/cpp/client/create_channel_internal.h" namespace grpc { -class ChannelArguments; std::shared_ptr CreateChannel( const grpc::string& target, diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index 214d72f853f..ba7be1c1026 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -27,11 +27,11 @@ #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/socket_mutator.h" -namespace grpc { +namespace grpc_impl { ChannelArguments::ChannelArguments() { // This will be ignored if used on the server side. - SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + Version()); + SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, "grpc-c++/" + grpc::Version()); } ChannelArguments::ChannelArguments(const ChannelArguments& other) @@ -215,4 +215,4 @@ void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const { } } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/common/secure_channel_arguments.cc b/src/cpp/common/secure_channel_arguments.cc index 2fb8ea44fbc..e5d03cd2378 100644 --- a/src/cpp/common/secure_channel_arguments.cc +++ b/src/cpp/common/secure_channel_arguments.cc @@ -21,7 +21,7 @@ #include #include "src/core/lib/channel/channel_args.h" -namespace grpc { +namespace grpc_impl { void ChannelArguments::SetSslTargetNameOverride(const grpc::string& name) { SetString(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, name); @@ -36,4 +36,4 @@ grpc::string ChannelArguments::GetSslTargetNameOverride() const { return ""; } -} // namespace grpc +} // namespace grpc_impl From 9b42ab79e087879dfebaab618bd63d019d322834 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 4 Apr 2019 16:40:16 -0700 Subject: [PATCH 014/112] Make build fixes for bazel build :all --- include/grpcpp/impl/server_builder_plugin.h | 2 +- include/grpcpp/security/credentials.h | 1 - include/grpcpp/support/channel_arguments_impl.h | 2 +- src/cpp/client/create_channel.cc | 4 ---- 4 files changed, 2 insertions(+), 7 deletions(-) diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 9ab40bd7615..ccc8b832760 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -26,10 +26,10 @@ namespace grpc_impl { class ChannelArguments; -class ServerBuilder; class ServerInitializer; } // namespace grpc_impl namespace grpc { +class ServerBuilder; /// This interface is meant for internal usage only. Implementations of this /// interface should add themselves to a \a ServerBuilder instance through the diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 43f68f3a9fa..8662b068a59 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -35,7 +35,6 @@ struct grpc_call; namespace grpc { class CallCredentials; -class ChannelArguments; class ChannelCredentials; } // namespace grpc namespace grpc_impl { diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 1e1340e716d..8276c1d9099 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -24,6 +24,7 @@ #include #include +#include #include namespace grpc { @@ -31,7 +32,6 @@ namespace testing { class ChannelArgumentsTest; } // namespace testing -class ResourceQuota; class SecureChannelCredentials; } // namespace grpc diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index 9426a4e7f6e..15bc193af72 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -25,10 +25,6 @@ #include "src/cpp/client/create_channel_internal.h" -namespace grpc { - -class ChannelArguments; -} namespace grpc_impl { std::shared_ptr CreateChannel( const grpc::string& target, From 2378ddcd51fb7a9529fe4bfce6f8802c6f1878f4 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 9 Apr 2019 22:23:10 -0700 Subject: [PATCH 015/112] Add service config to call context --- .../ext/filters/client_channel/client_channel.cc | 16 +++++++++++++--- .../client_channel/resolver_result_parsing.h | 1 + src/core/lib/channel/context.h | 2 ++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index cd552739732..049c8d0a13f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -170,6 +170,7 @@ struct client_channel_channel_data { bool received_service_config_data; grpc_core::RefCountedPtr retry_throttle_data; grpc_core::RefCountedPtr method_params_table; + grpc_core::RefCountedPtr service_config; // // Fields used in the control plane. Protected by combiner. @@ -276,10 +277,12 @@ class ServiceConfigSetter { ServiceConfigSetter( channel_data* chand, RefCountedPtr retry_throttle_data, - RefCountedPtr method_params_table) + RefCountedPtr method_params_table, + RefCountedPtr service_config) : chand_(chand), retry_throttle_data_(std::move(retry_throttle_data)), - method_params_table_(std::move(method_params_table)) { + method_params_table_(std::move(method_params_table)), + service_config_(std::move(service_config)) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "ServiceConfigSetter"); GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, grpc_combiner_scheduler(chand->data_plane_combiner)); @@ -294,6 +297,7 @@ class ServiceConfigSetter { chand->received_service_config_data = true; chand->retry_throttle_data = std::move(self->retry_throttle_data_); chand->method_params_table = std::move(self->method_params_table_); + chand->service_config = std::move(self->service_config_); // Apply service config to queued picks. for (QueuedPick* pick = chand->queued_picks; pick != nullptr; pick = pick->next) { @@ -307,6 +311,7 @@ class ServiceConfigSetter { channel_data* chand_; RefCountedPtr retry_throttle_data_; RefCountedPtr method_params_table_; + RefCountedPtr service_config_; grpc_closure closure_; }; @@ -505,7 +510,7 @@ static bool process_resolver_result_locked( // plane combiner. Destroys itself when done. grpc_core::New( chand, resolver_result.retry_throttle_data(), - resolver_result.method_params_table()); + resolver_result.method_params_table(), resolver_result.service_config()); // Swap out the data used by cc_get_channel_info(). gpr_mu_lock(&chand->info_mu); chand->info_lb_policy_name = resolver_result.lb_policy_name(); @@ -970,6 +975,7 @@ struct call_data { grpc_core::RefCountedPtr retry_throttle_data; grpc_core::RefCountedPtr method_params; + grpc_core::RefCountedPtr service_config; grpc_core::RefCountedPtr subchannel_call; @@ -2813,6 +2819,10 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, calld); } + if(chand->service_config != nullptr) { + calld->service_config = chand->service_config; + calld->call_context[GRPC_SERVICE_CONFIG].value = &calld->service_config; + } if (chand->retry_throttle_data != nullptr) { calld->retry_throttle_data = chand->retry_throttle_data->Ref(); } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 1a46278f38b..ad40c4991fe 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -64,6 +64,7 @@ class ProcessedResolverResult { RefCountedPtr lb_policy_config() { return std::move(lb_policy_config_); } + RefCountedPtr service_config() { return service_config_; } private: // Finds the service config; extracts LB config and (maybe) retry throttle diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 81b84f1ca05..722c22c4623 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -35,6 +35,8 @@ typedef enum { /// Reserved for traffic_class_context. GRPC_CONTEXT_TRAFFIC, + GRPC_SERVICE_CONFIG, + GRPC_CONTEXT_COUNT } grpc_context_index; From 2e88231fc027de4b7728adc05642bb9e96bfec75 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 10 Apr 2019 15:04:05 -0700 Subject: [PATCH 016/112] Revert "Revert "Merge pull request #18458 from grpc/grpc_namespace_server"" --- BUILD | 1 + BUILD.gn | 1 + CMakeLists.txt | 3 + Makefile | 3 + build.yaml | 1 + gRPC-C++.podspec | 1 + .../impl/codegen/async_generic_service.h | 10 +- include/grpcpp/impl/codegen/async_stream.h | 2 +- .../grpcpp/impl/codegen/completion_queue.h | 10 +- include/grpcpp/impl/codegen/server_context.h | 7 +- include/grpcpp/impl/codegen/service_type.h | 7 +- include/grpcpp/impl/server_initializer_impl.h | 2 +- include/grpcpp/security/server_credentials.h | 4 + .../grpcpp/security/server_credentials_impl.h | 4 +- include/grpcpp/server.h | 328 +--------- include/grpcpp/server_builder.h | 1 + include/grpcpp/server_builder_impl.h | 2 +- src/cpp/server/server_cc.cc | 602 +++++++++--------- test/cpp/util/metrics_server.h | 2 + tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + .../generated/sources_and_headers.json | 2 + 22 files changed, 360 insertions(+), 635 deletions(-) diff --git a/BUILD b/BUILD index b0c501455d1..19e370014e3 100644 --- a/BUILD +++ b/BUILD @@ -255,6 +255,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", diff --git a/BUILD.gn b/BUILD.gn index 7f5157377a7..57e15800e20 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1090,6 +1090,7 @@ config("grpc_config") { "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index cce21957659..86dcbb320d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3038,6 +3038,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h @@ -3641,6 +3642,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h @@ -4620,6 +4622,7 @@ foreach(_hdr include/grpcpp/server_builder.h include/grpcpp/server_builder_impl.h include/grpcpp/server_context.h + include/grpcpp/server_impl.h include/grpcpp/server_posix.h include/grpcpp/server_posix_impl.h include/grpcpp/support/async_stream.h diff --git a/Makefile b/Makefile index d972215250a..66f96985bdb 100644 --- a/Makefile +++ b/Makefile @@ -5373,6 +5373,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ @@ -5984,6 +5985,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ @@ -6912,6 +6914,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ + include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ diff --git a/build.yaml b/build.yaml index 9e78ec4efa3..a786546c231 100644 --- a/build.yaml +++ b/build.yaml @@ -1384,6 +1384,7 @@ filegroups: - include/grpcpp/server_builder.h - include/grpcpp/server_builder_impl.h - include/grpcpp/server_context.h + - include/grpcpp/server_impl.h - include/grpcpp/server_posix.h - include/grpcpp/server_posix_impl.h - include/grpcpp/support/async_stream.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index b8e4d80b838..7f1ae557537 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -122,6 +122,7 @@ Pod::Spec.new do |s| 'include/grpcpp/server_builder.h', 'include/grpcpp/server_builder_impl.h', 'include/grpcpp/server_context.h', + 'include/grpcpp/server_impl.h', 'include/grpcpp/server_posix.h', 'include/grpcpp/server_posix_impl.h', 'include/grpcpp/support/async_stream.h', diff --git a/include/grpcpp/impl/codegen/async_generic_service.h b/include/grpcpp/impl/codegen/async_generic_service.h index 759f6683bf4..46d09121a7b 100644 --- a/include/grpcpp/impl/codegen/async_generic_service.h +++ b/include/grpcpp/impl/codegen/async_generic_service.h @@ -39,7 +39,7 @@ class GenericServerContext final : public ServerContext { const grpc::string& host() const { return host_; } private: - friend class Server; + friend class grpc_impl::Server; friend class ServerInterface; void Clear() { @@ -79,8 +79,8 @@ class AsyncGenericService final { ServerCompletionQueue* notification_cq, void* tag); private: - friend class Server; - Server* server_; + friend class grpc_impl::Server; + grpc_impl::Server* server_; }; namespace experimental { @@ -135,14 +135,14 @@ class CallbackGenericService { } private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; internal::CallbackBidiHandler* Handler() { return new internal::CallbackBidiHandler( [this] { return CreateReactor(); }); } - Server* server_{nullptr}; + grpc_impl::Server* server_{nullptr}; }; } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/impl/codegen/async_stream.h b/include/grpcpp/impl/codegen/async_stream.h index bfb2df4f232..e12923ea02c 100644 --- a/include/grpcpp/impl/codegen/async_stream.h +++ b/include/grpcpp/impl/codegen/async_stream.h @@ -1099,7 +1099,7 @@ class ServerAsyncReaderWriter final } private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; void BindCall(::grpc::internal::Call* call) override { call_ = *call; } diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index 73556ce9899..85eee6f34bf 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -43,8 +43,9 @@ struct grpc_completion_queue; namespace grpc_impl { +class Server; class ServerBuilder; -} +} // namespace grpc_impl namespace grpc { template @@ -66,7 +67,6 @@ class Channel; class ChannelInterface; class ClientContext; class CompletionQueue; -class Server; class ServerContext; class ServerInterface; @@ -274,7 +274,7 @@ class CompletionQueue : private GrpcLibraryCodegen { friend class ::grpc::internal::TemplatedBidiStreamingHandler; template friend class ::grpc::internal::ErrorMethodHandler; - friend class ::grpc::Server; + friend class ::grpc_impl::Server; friend class ::grpc::ServerContext; friend class ::grpc::ServerInterface; template @@ -408,8 +408,8 @@ class ServerCompletionQueue : public CompletionQueue { polling_type_(polling_type) {} grpc_cq_polling_type polling_type_; - friend class ::grpc_impl::ServerBuilder; - friend class Server; + friend class grpc_impl::ServerBuilder; + friend class grpc_impl::Server; }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h index 591a9ff9549..f65598db41f 100644 --- a/include/grpcpp/impl/codegen/server_context.h +++ b/include/grpcpp/impl/codegen/server_context.h @@ -41,11 +41,14 @@ struct grpc_metadata; struct grpc_call; struct census_context; +namespace grpc_impl { + +class Server; +} // namespace grpc_impl namespace grpc { class ClientContext; class GenericServerContext; class CompletionQueue; -class Server; class ServerInterface; template class ServerAsyncReader; @@ -269,7 +272,7 @@ class ServerContext { friend class ::grpc::testing::InteropServerContextInspector; friend class ::grpc::testing::ServerContextTestSpouse; friend class ::grpc::ServerInterface; - friend class ::grpc::Server; + friend class ::grpc_impl::Server; template friend class ::grpc::ServerAsyncReader; template diff --git a/include/grpcpp/impl/codegen/service_type.h b/include/grpcpp/impl/codegen/service_type.h index 332a04c294f..1d94abe12dd 100644 --- a/include/grpcpp/impl/codegen/service_type.h +++ b/include/grpcpp/impl/codegen/service_type.h @@ -26,10 +26,13 @@ #include #include +namespace grpc_impl { + +class Server; +} // namespace grpc_impl namespace grpc { class CompletionQueue; -class Server; class ServerInterface; class ServerCompletionQueue; class ServerContext; @@ -228,7 +231,7 @@ class Service { } private: - friend class Server; + friend class grpc_impl::Server; friend class ServerInterface; ServerInterface* server_; std::vector> methods_; diff --git a/include/grpcpp/impl/server_initializer_impl.h b/include/grpcpp/impl/server_initializer_impl.h index ff610efa2ac..0e2c65f4af4 100644 --- a/include/grpcpp/impl/server_initializer_impl.h +++ b/include/grpcpp/impl/server_initializer_impl.h @@ -26,10 +26,10 @@ namespace grpc { -class Server; class Service; } // namespace grpc namespace grpc_impl { +class Server; class ServerInitializer { public: diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index 7e643ae7400..57f733886f4 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -21,6 +21,10 @@ #include +namespace grpc_impl { + +class Server; +} // namespace grpc_impl namespace grpc { typedef ::grpc_impl::ServerCredentials ServerCredentials; diff --git a/include/grpcpp/security/server_credentials_impl.h b/include/grpcpp/security/server_credentials_impl.h index afe8d22650b..f08849097ad 100644 --- a/include/grpcpp/security/server_credentials_impl.h +++ b/include/grpcpp/security/server_credentials_impl.h @@ -30,10 +30,10 @@ struct grpc_server; namespace grpc { -class Server; struct SslServerCredentialsOptions; } // namespace grpc namespace grpc_impl { +class Server; /// Wrapper around \a grpc_server_credentials, a way to authenticate a server. class ServerCredentials { @@ -46,7 +46,7 @@ class ServerCredentials { const std::shared_ptr& processor) = 0; private: - friend class ::grpc::Server; + friend class ::grpc_impl::Server; /// Tries to bind \a server to the given \a addr (eg, localhost:1234, /// 192.168.1.1:31416, [::1]:27182, etc.) diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h index 8aff0663fe2..3de2aba0b59 100644 --- a/include/grpcpp/server.h +++ b/include/grpcpp/server.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,333 +19,11 @@ #ifndef GRPCPP_SERVER_H #define GRPCPP_SERVER_H -#include -#include -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_server; - -namespace grpc_impl { - -class ServerInitializer; -} namespace grpc { -class AsyncGenericService; -class ServerContext; - -/// Represents a gRPC server. -/// -/// Use a \a grpc::ServerBuilder to create, configure, and start -/// \a Server instances. -class Server : public ServerInterface, private GrpcLibraryCodegen { - public: - ~Server(); - - /// Block until the server shuts down. - /// - /// \warning The server must be either shutting down or some other thread must - /// call \a Shutdown for this function to ever return. - void Wait() override; - - /// Global callbacks are a set of hooks that are called when server - /// events occur. \a SetGlobalCallbacks method is used to register - /// the hooks with gRPC. Note that - /// the \a GlobalCallbacks instance will be shared among all - /// \a Server instances in an application and can be set exactly - /// once per application. - class GlobalCallbacks { - public: - virtual ~GlobalCallbacks() {} - /// Called before server is created. - virtual void UpdateArguments(ChannelArguments* args) {} - /// Called before application callback for each synchronous server request - virtual void PreSynchronousRequest(ServerContext* context) = 0; - /// Called after application callback for each synchronous server request - virtual void PostSynchronousRequest(ServerContext* context) = 0; - /// Called before server is started. - virtual void PreServerStart(Server* server) {} - /// Called after a server port is added. - virtual void AddPort(Server* server, const grpc::string& addr, - ServerCredentials* creds, int port) {} - }; - /// Set the global callback object. Can only be called once per application. - /// Does not take ownership of callbacks, and expects the pointed to object - /// to be alive until all server objects in the process have been destroyed. - /// The same \a GlobalCallbacks object will be used throughout the - /// application and is shared among all \a Server objects. - static void SetGlobalCallbacks(GlobalCallbacks* callbacks); - - /// Returns a \em raw pointer to the underlying \a grpc_server instance. - /// EXPERIMENTAL: for internal/test use only - grpc_server* c_server(); - - /// Returns the health check service. - HealthCheckServiceInterface* GetHealthCheckService() const { - return health_check_service_.get(); - } - - /// Establish a channel for in-process communication - std::shared_ptr InProcessChannel(const ChannelArguments& args); - - /// NOTE: class experimental_type is not part of the public API of this class. - /// TODO(yashykt): Integrate into public API when this is no longer - /// experimental. - class experimental_type { - public: - explicit experimental_type(Server* server) : server_(server) {} - - /// Establish a channel for in-process communication with client - /// interceptors - std::shared_ptr InProcessChannelWithInterceptors( - const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); - - private: - Server* server_; - }; - - /// NOTE: The function experimental() is not stable public API. It is a view - /// to the experimental components of this class. It may be changed or removed - /// at any time. - experimental_type experimental() { return experimental_type(this); } - - protected: - /// Register a service. This call does not take ownership of the service. - /// The service must exist for the lifetime of the Server instance. - bool RegisterService(const grpc::string* host, Service* service) override; - - /// Try binding the server to the given \a addr endpoint - /// (port, and optionally including IP address to bind to). - /// - /// It can be invoked multiple times. Should be used before - /// starting the server. - /// - /// \param addr The address to try to bind to the server (eg, localhost:1234, - /// 192.168.1.1:31416, [::1]:27182, etc.). - /// \param creds The credentials associated with the server. - /// - /// \return bound port number on success, 0 on failure. - /// - /// \warning It is an error to call this method on an already started server. - int AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) override; - - /// NOTE: This is *NOT* a public API. The server constructors are supposed to - /// be used by \a ServerBuilder class only. The constructor will be made - /// 'private' very soon. - /// - /// Server constructors. To be used by \a ServerBuilder only. - /// - /// \param max_message_size Maximum message length that the channel can - /// receive. - /// - /// \param args The channel args - /// - /// \param sync_server_cqs The completion queues to use if the server is a - /// synchronous server (or a hybrid server). The server polls for new RPCs on - /// these queues - /// - /// \param min_pollers The minimum number of polling threads per server - /// completion queue (in param sync_server_cqs) to use for listening to - /// incoming requests (used only in case of sync server) - /// - /// \param max_pollers The maximum number of polling threads per server - /// completion queue (in param sync_server_cqs) to use for listening to - /// incoming requests (used only in case of sync server) - /// - /// \param sync_cq_timeout_msec The timeout to use when calling AsyncNext() on - /// server completion queues passed via sync_server_cqs param. - Server(int max_message_size, ChannelArguments* args, - std::shared_ptr>> - sync_server_cqs, - int min_pollers, int max_pollers, int sync_cq_timeout_msec, - grpc_resource_quota* server_rq = nullptr, - std::vector< - std::unique_ptr> - interceptor_creators = std::vector>()); - - /// Start the server. - /// - /// \param cqs Completion queues for handling asynchronous services. The - /// caller is required to keep all completion queues live until the server is - /// destroyed. - /// \param num_cqs How many completion queues does \a cqs hold. - void Start(ServerCompletionQueue** cqs, size_t num_cqs) override; - - grpc_server* server() override { return server_; } - - private: - std::vector>* - interceptor_creators() override { - return &interceptor_creators_; - } - - friend class AsyncGenericService; - friend class grpc_impl::ServerBuilder; - friend class grpc_impl::ServerInitializer; - - class SyncRequest; - class CallbackRequestBase; - template - class CallbackRequest; - class UnimplementedAsyncRequest; - class UnimplementedAsyncResponse; - - /// SyncRequestThreadManager is an implementation of ThreadManager. This class - /// is responsible for polling for incoming RPCs and calling the RPC handlers. - /// This is only used in case of a Sync server (i.e a server exposing a sync - /// interface) - class SyncRequestThreadManager; - - /// Register a generic service. This call does not take ownership of the - /// service. The service must exist for the lifetime of the Server instance. - void RegisterAsyncGenericService(AsyncGenericService* service) override; - - /// NOTE: class experimental_registration_type is not part of the public API - /// of this class - /// TODO(vjpai): Move these contents to the public API of Server when - /// they are no longer experimental - class experimental_registration_type final - : public experimental_registration_interface { - public: - explicit experimental_registration_type(Server* server) : server_(server) {} - void RegisterCallbackGenericService( - experimental::CallbackGenericService* service) override { - server_->RegisterCallbackGenericService(service); - } - - private: - Server* server_; - }; - - /// TODO(vjpai): Mark this override when experimental type above is deleted - void RegisterCallbackGenericService( - experimental::CallbackGenericService* service); - - /// NOTE: The function experimental_registration() is not stable public API. - /// It is a view to the experimental components of this class. It may be - /// changed or removed at any time. - experimental_registration_interface* experimental_registration() override { - return &experimental_registration_; - } - - void PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) override; - - void ShutdownInternal(gpr_timespec deadline) override; - - int max_receive_message_size() const override { - return max_receive_message_size_; - } - - CompletionQueue* CallbackCQ() override; - - grpc_impl::ServerInitializer* initializer(); - - // A vector of interceptor factory objects. - // This should be destroyed after health_check_service_ and this requirement - // is satisfied by declaring interceptor_creators_ before - // health_check_service_. (C++ mandates that member objects be destroyed in - // the reverse order of initialization.) - std::vector> - interceptor_creators_; - - const int max_receive_message_size_; - - /// The following completion queues are ONLY used in case of Sync API - /// i.e. if the server has any services with sync methods. The server uses - /// these completion queues to poll for new RPCs - std::shared_ptr>> - sync_server_cqs_; - - /// List of \a ThreadManager instances (one for each cq in - /// the \a sync_server_cqs) - std::vector> sync_req_mgrs_; - - // Outstanding unmatched callback requests, indexed by method. - // NOTE: Using a gpr_atm rather than atomic_int because atomic_int isn't - // copyable or movable and thus will cause compilation errors. We - // actually only want to extend the vector before the threaded use - // starts, but this is still a limitation. - std::vector callback_unmatched_reqs_count_; - - // List of callback requests to start when server actually starts. - std::list callback_reqs_to_start_; - - // For registering experimental callback generic service; remove when that - // method longer experimental - experimental_registration_type experimental_registration_{this}; - - // Server status - grpc::internal::Mutex mu_; - bool started_; - bool shutdown_; - bool shutdown_notified_; // Was notify called on the shutdown_cv_ - - grpc::internal::CondVar shutdown_cv_; - - // It is ok (but not required) to nest callback_reqs_mu_ under mu_ . - // Incrementing callback_reqs_outstanding_ is ok without a lock but it must be - // decremented under the lock in case it is the last request and enables the - // server shutdown. The increment is performance-critical since it happens - // during periods of increasing load; the decrement happens only when memory - // is maxed out, during server shutdown, or (possibly in a future version) - // during decreasing load, so it is less performance-critical. - grpc::internal::Mutex callback_reqs_mu_; - grpc::internal::CondVar callback_reqs_done_cv_; - std::atomic_int callback_reqs_outstanding_{0}; - - std::shared_ptr global_callbacks_; - - std::vector services_; - bool has_async_generic_service_{false}; - bool has_callback_generic_service_{false}; - - // Pointer to the wrapped grpc_server. - grpc_server* server_; - - std::unique_ptr server_initializer_; - - std::unique_ptr health_check_service_; - bool health_check_service_disabled_; - - // When appropriate, use a default callback generic service to handle - // unimplemented methods - std::unique_ptr unimplemented_service_; - - // A special handler for resource exhausted in sync case - std::unique_ptr resource_exhausted_handler_; - - // Handler for callback generic service, if any - std::unique_ptr generic_handler_; - - // callback_cq_ references the callbackable completion queue associated - // with this server (if any). It is set on the first call to CallbackCQ(). - // It is _not owned_ by the server; ownership belongs with its internal - // shutdown callback tag (invoked when the CQ is fully shutdown). - // It is protected by mu_ - CompletionQueue* callback_cq_ = nullptr; -}; +typedef ::grpc_impl::Server Server; } // namespace grpc diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index 33689561825..89c4eba1d95 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -23,6 +23,7 @@ namespace grpc_impl { +class Server; class ServerCredentials; class ResourceQuota; } // namespace grpc_impl diff --git a/include/grpcpp/server_builder_impl.h b/include/grpcpp/server_builder_impl.h index 25b8091a7df..f7624deba5f 100644 --- a/include/grpcpp/server_builder_impl.h +++ b/include/grpcpp/server_builder_impl.h @@ -31,6 +31,7 @@ #include #include #include +#include #include struct grpc_resource_quota; @@ -44,7 +45,6 @@ namespace grpc { class AsyncGenericService; class CompletionQueue; -class Server; class ServerCompletionQueue; class Service; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 64a6de97d7e..4f0fdefceda 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -106,15 +106,183 @@ class UnimplementedAsyncRequestContext { } // namespace +ServerInterface::BaseAsyncRequest::BaseAsyncRequest( + ServerInterface* server, ServerContext* context, + internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, + ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize) + : server_(server), + context_(context), + stream_(stream), + call_cq_(call_cq), + notification_cq_(notification_cq), + tag_(tag), + delete_on_finalize_(delete_on_finalize), + call_(nullptr), + done_intercepting_(false) { + /* Set up interception state partially for the receive ops. call_wrapper_ is + * not filled at this point, but it will be filled before the interceptors are + * run. */ + interceptor_methods_.SetCall(&call_wrapper_); + interceptor_methods_.SetReverse(); + call_cq_->RegisterAvalanching(); // This op will trigger more ops +} + +ServerInterface::BaseAsyncRequest::~BaseAsyncRequest() { + call_cq_->CompleteAvalanching(); +} + +bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, + bool* status) { + if (done_intercepting_) { + *tag = tag_; + if (delete_on_finalize_) { + delete this; + } + return true; + } + context_->set_call(call_); + context_->cq_ = call_cq_; + if (call_wrapper_.call() == nullptr) { + // Fill it since it is empty. + call_wrapper_ = internal::Call( + call_, server_, call_cq_, server_->max_receive_message_size(), nullptr); + } + + // just the pointers inside call are copied here + stream_->BindCall(&call_wrapper_); + + if (*status && call_ && call_wrapper_.server_rpc_info()) { + done_intercepting_ = true; + // Set interception point for RECV INITIAL METADATA + interceptor_methods_.AddInterceptionHookPoint( + experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); + interceptor_methods_.SetRecvInitialMetadata(&context_->client_metadata_); + if (interceptor_methods_.RunInterceptors( + [this]() { ContinueFinalizeResultAfterInterception(); })) { + // There are no interceptors to run. Continue + } else { + // There were interceptors to be run, so + // ContinueFinalizeResultAfterInterception will be run when interceptors + // are done. + return false; + } + } + if (*status && call_) { + context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); + } + *tag = tag_; + if (delete_on_finalize_) { + delete this; + } + return true; +} + +void ServerInterface::BaseAsyncRequest:: + ContinueFinalizeResultAfterInterception() { + context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); + // Queue a tag which will be returned immediately + grpc_core::ExecCtx exec_ctx; + grpc_cq_begin_op(notification_cq_->cq(), this); + grpc_cq_end_op( + notification_cq_->cq(), this, GRPC_ERROR_NONE, + [](void* arg, grpc_cq_completion* completion) { delete completion; }, + nullptr, new grpc_cq_completion()); +} + +ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest( + ServerInterface* server, ServerContext* context, + internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, + ServerCompletionQueue* notification_cq, void* tag, const char* name, + internal::RpcMethod::RpcType type) + : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag, + true), + name_(name), + type_(type) {} + +void ServerInterface::RegisteredAsyncRequest::IssueRequest( + void* registered_method, grpc_byte_buffer** payload, + ServerCompletionQueue* notification_cq) { + GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_registered_call( + server_->server(), registered_method, &call_, + &context_->deadline_, + context_->client_metadata_.arr(), payload, + call_cq_->cq(), notification_cq->cq(), this)); +} + +ServerInterface::GenericAsyncRequest::GenericAsyncRequest( + ServerInterface* server, GenericServerContext* context, + internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, + ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize) + : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag, + delete_on_finalize) { + grpc_call_details_init(&call_details_); + GPR_ASSERT(notification_cq); + GPR_ASSERT(call_cq); + GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( + server->server(), &call_, &call_details_, + context->client_metadata_.arr(), call_cq->cq(), + notification_cq->cq(), this)); +} + +bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag, + bool* status) { + // If we are done intercepting, there is nothing more for us to do + if (done_intercepting_) { + return BaseAsyncRequest::FinalizeResult(tag, status); + } + // TODO(yangg) remove the copy here. + if (*status) { + static_cast(context_)->method_ = + StringFromCopiedSlice(call_details_.method); + static_cast(context_)->host_ = + StringFromCopiedSlice(call_details_.host); + context_->deadline_ = call_details_.deadline; + } + grpc_slice_unref(call_details_.method); + grpc_slice_unref(call_details_.host); + call_wrapper_ = internal::Call( + call_, server_, call_cq_, server_->max_receive_message_size(), + context_->set_server_rpc_info( + static_cast(context_)->method_.c_str(), + internal::RpcMethod::BIDI_STREAMING, + *server_->interceptor_creators())); + return BaseAsyncRequest::FinalizeResult(tag, status); +} + +namespace { +class ShutdownCallback : public grpc_experimental_completion_queue_functor { + public: + ShutdownCallback() { functor_run = &ShutdownCallback::Run; } + // TakeCQ takes ownership of the cq into the shutdown callback + // so that the shutdown callback will be responsible for destroying it + void TakeCQ(CompletionQueue* cq) { cq_ = cq; } + + // The Run function will get invoked by the completion queue library + // when the shutdown is actually complete + static void Run(grpc_experimental_completion_queue_functor* cb, int) { + auto* callback = static_cast(cb); + delete callback->cq_; + delete callback; + } + + private: + CompletionQueue* cq_ = nullptr; +}; +} // namespace + +} // namespace grpc + +namespace grpc_impl { + /// Use private inheritance rather than composition only to establish order /// of construction, since the public base class should be constructed after the /// elements belonging to the private base class are constructed. This is not /// possible using true composition. class Server::UnimplementedAsyncRequest final - : private UnimplementedAsyncRequestContext, + : private grpc::UnimplementedAsyncRequestContext, public GenericAsyncRequest { public: - UnimplementedAsyncRequest(Server* server, ServerCompletionQueue* cq) + UnimplementedAsyncRequest(Server* server, grpc::ServerCompletionQueue* cq) : GenericAsyncRequest(server, &server_context_, &generic_stream_, cq, cq, nullptr, false), server_(server), @@ -122,27 +290,29 @@ class Server::UnimplementedAsyncRequest final bool FinalizeResult(void** tag, bool* status) override; - ServerContext* context() { return &server_context_; } - GenericServerAsyncReaderWriter* stream() { return &generic_stream_; } + grpc::ServerContext* context() { return &server_context_; } + grpc::GenericServerAsyncReaderWriter* stream() { return &generic_stream_; } private: Server* const server_; - ServerCompletionQueue* const cq_; + grpc::ServerCompletionQueue* const cq_; }; /// UnimplementedAsyncResponse should not post user-visible completions to the /// C++ completion queue, but is generated as a CQ event by the core class Server::UnimplementedAsyncResponse final - : public internal::CallOpSet { + : public grpc::internal::CallOpSet< + grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpServerSendStatus> { public: UnimplementedAsyncResponse(UnimplementedAsyncRequest* request); ~UnimplementedAsyncResponse() { delete request_; } bool FinalizeResult(void** tag, bool* status) override { - if (internal::CallOpSet< - internal::CallOpSendInitialMetadata, - internal::CallOpServerSendStatus>::FinalizeResult(tag, status)) { + if (grpc::internal::CallOpSet< + grpc::internal::CallOpSendInitialMetadata, + grpc::internal::CallOpServerSendStatus>::FinalizeResult(tag, + status)) { delete this; } else { // The tag was swallowed due to interception. We will see it again. @@ -154,15 +324,16 @@ class Server::UnimplementedAsyncResponse final UnimplementedAsyncRequest* const request_; }; -class Server::SyncRequest final : public internal::CompletionQueueTag { +class Server::SyncRequest final : public grpc::internal::CompletionQueueTag { public: - SyncRequest(internal::RpcServiceMethod* method, void* method_tag) + SyncRequest(grpc::internal::RpcServiceMethod* method, void* method_tag) : method_(method), method_tag_(method_tag), in_flight_(false), - has_request_payload_( - method->method_type() == internal::RpcMethod::NORMAL_RPC || - method->method_type() == internal::RpcMethod::SERVER_STREAMING), + has_request_payload_(method->method_type() == + grpc::internal::RpcMethod::NORMAL_RPC || + method->method_type() == + grpc::internal::RpcMethod::SERVER_STREAMING), call_details_(nullptr), cq_(nullptr) { grpc_metadata_array_init(&request_metadata_); @@ -273,7 +444,8 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { interceptor_methods_.SetReverse(); // Set interception point for RECV INITIAL METADATA interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); + grpc::experimental::InterceptionHookPoints:: + POST_RECV_INITIAL_METADATA); interceptor_methods_.SetRecvInitialMetadata(&ctx_.client_metadata_); if (has_request_payload_) { @@ -285,7 +457,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { request_payload_ = nullptr; interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE); interceptor_methods_.SetRecvMessage(request_, nullptr); } @@ -304,40 +476,40 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { global_callbacks_->PreSynchronousRequest(&ctx_); auto* handler = resources_ ? method_->handler() : server_->resource_exhausted_handler_.get(); - handler->RunHandler(internal::MethodHandler::HandlerParameter( + handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter( &call_, &ctx_, request_, request_status_, nullptr)); request_ = nullptr; global_callbacks_->PostSynchronousRequest(&ctx_); cq_.Shutdown(); - internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag(); + grpc::internal::CompletionQueueTag* op_tag = ctx_.GetCompletionOpTag(); cq_.TryPluck(op_tag, gpr_inf_future(GPR_CLOCK_REALTIME)); /* Ensure the cq_ is shutdown */ - DummyTag ignored_tag; + grpc::DummyTag ignored_tag; GPR_ASSERT(cq_.Pluck(&ignored_tag) == false); } delete this; } private: - CompletionQueue cq_; - ServerContext ctx_; + grpc::CompletionQueue cq_; + grpc::ServerContext ctx_; const bool has_request_payload_; grpc_byte_buffer* request_payload_; void* request_; - Status request_status_; - internal::RpcServiceMethod* const method_; - internal::Call call_; + grpc::Status request_status_; + grpc::internal::RpcServiceMethod* const method_; + grpc::internal::Call call_; Server* server_; std::shared_ptr global_callbacks_; bool resources_; - internal::InterceptorBatchMethodsImpl interceptor_methods_; + grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_; }; private: - internal::RpcServiceMethod* const method_; + grpc::internal::RpcServiceMethod* const method_; void* const method_tag_; bool in_flight_; const bool has_request_payload_; @@ -349,7 +521,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag { grpc_completion_queue* cq_; }; -class Server::CallbackRequestBase : public internal::CompletionQueueTag { +class Server::CallbackRequestBase : public grpc::internal::CompletionQueueTag { public: virtual ~CallbackRequestBase() {} virtual bool Request() = 0; @@ -358,7 +530,7 @@ class Server::CallbackRequestBase : public internal::CompletionQueueTag { template class Server::CallbackRequest final : public Server::CallbackRequestBase { public: - static_assert(std::is_base_of::value, + static_assert(std::is_base_of::value, "ServerContextType must be derived from ServerContext"); // The constructor needs to know the server for this callback request and its @@ -368,15 +540,16 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { // requested. For generic services, method and method_tag are nullptr since // these services don't have pre-defined methods or method registration tags. CallbackRequest(Server* server, size_t method_idx, - internal::RpcServiceMethod* method, void* method_tag) + grpc::internal::RpcServiceMethod* method, void* method_tag) : server_(server), method_index_(method_idx), method_(method), method_tag_(method_tag), has_request_payload_( method_ != nullptr && - (method->method_type() == internal::RpcMethod::NORMAL_RPC || - method->method_type() == internal::RpcMethod::SERVER_STREAMING)), + (method->method_type() == grpc::internal::RpcMethod::NORMAL_RPC || + method->method_type() == + grpc::internal::RpcMethod::SERVER_STREAMING)), cq_(server->CallbackCQ()), tag_(this) { server_->callback_reqs_outstanding_++; @@ -440,7 +613,7 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { private: Server::CallbackRequest* req_; - internal::Call* call_; + grpc::internal::Call* call_; static void StaticRun(grpc_experimental_completion_queue_functor* cb, int ok) { @@ -491,21 +664,24 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { req_->request_metadata_.count = 0; // Create a C++ Call to control the underlying core call - call_ = new (grpc_call_arena_alloc(req_->call_, sizeof(internal::Call))) - internal::Call(req_->call_, req_->server_, req_->cq_, - req_->server_->max_receive_message_size(), - req_->ctx_.set_server_rpc_info( - req_->method_name(), - (req_->method_ != nullptr) - ? req_->method_->method_type() - : internal::RpcMethod::BIDI_STREAMING, - req_->server_->interceptor_creators_)); + call_ = + new (grpc_call_arena_alloc(req_->call_, sizeof(grpc::internal::Call))) + grpc::internal::Call( + req_->call_, req_->server_, req_->cq_, + req_->server_->max_receive_message_size(), + req_->ctx_.set_server_rpc_info( + req_->method_name(), + (req_->method_ != nullptr) + ? req_->method_->method_type() + : grpc::internal::RpcMethod::BIDI_STREAMING, + req_->server_->interceptor_creators_)); req_->interceptor_methods_.SetCall(call_); req_->interceptor_methods_.SetReverse(); // Set interception point for RECV INITIAL METADATA req_->interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); + grpc::experimental::InterceptionHookPoints:: + POST_RECV_INITIAL_METADATA); req_->interceptor_methods_.SetRecvInitialMetadata( &req_->ctx_.client_metadata_); @@ -515,7 +691,7 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { req_->call_, req_->request_payload_, &req_->request_status_); req_->request_payload_ = nullptr; req_->interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_MESSAGE); + grpc::experimental::InterceptionHookPoints::POST_RECV_MESSAGE); req_->interceptor_methods_.SetRecvMessage(req_->request_, nullptr); } @@ -531,7 +707,7 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { auto* handler = (req_->method_ != nullptr) ? req_->method_->handler() : req_->server_->generic_handler_.get(); - handler->RunHandler(internal::MethodHandler::HandlerParameter( + handler->RunHandler(grpc::internal::MethodHandler::HandlerParameter( call_, &req_->ctx_, req_->request_, req_->request_status_, [this] { // Recycle this request if there aren't too many outstanding. // Note that we don't have to worry about a case where there @@ -577,40 +753,40 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); request_payload_ = nullptr; request_ = nullptr; - request_status_ = Status(); + request_status_ = grpc::Status(); } Server* const server_; const size_t method_index_; - internal::RpcServiceMethod* const method_; + grpc::internal::RpcServiceMethod* const method_; void* const method_tag_; const bool has_request_payload_; grpc_byte_buffer* request_payload_; void* request_; - Status request_status_; + grpc::Status request_status_; grpc_call_details* call_details_ = nullptr; grpc_call* call_; gpr_timespec deadline_; grpc_metadata_array request_metadata_; - CompletionQueue* cq_; + grpc::CompletionQueue* cq_; CallbackCallTag tag_; ServerContextType ctx_; - internal::InterceptorBatchMethodsImpl interceptor_methods_; + grpc::internal::InterceptorBatchMethodsImpl interceptor_methods_; }; template <> -bool Server::CallbackRequest::FinalizeResult(void** tag, - bool* status) { +bool Server::CallbackRequest::FinalizeResult( + void** tag, bool* status) { return false; } template <> -bool Server::CallbackRequest::FinalizeResult( +bool Server::CallbackRequest::FinalizeResult( void** tag, bool* status) { if (*status) { // TODO(yangg) remove the copy here - ctx_.method_ = StringFromCopiedSlice(call_details_->method); - ctx_.host_ = StringFromCopiedSlice(call_details_->host); + ctx_.method_ = grpc::StringFromCopiedSlice(call_details_->method); + ctx_.host_ = grpc::StringFromCopiedSlice(call_details_->host); } grpc_slice_unref(call_details_->method); grpc_slice_unref(call_details_->host); @@ -618,21 +794,22 @@ bool Server::CallbackRequest::FinalizeResult( } template <> -const char* Server::CallbackRequest::method_name() const { +const char* Server::CallbackRequest::method_name() const { return method_->name(); } template <> -const char* Server::CallbackRequest::method_name() const { +const char* Server::CallbackRequest::method_name() + const { return ctx_.method().c_str(); } // Implementation of ThreadManager. Each instance of SyncRequestThreadManager // manages a pool of threads that poll for incoming Sync RPCs and call the // appropriate RPC handlers -class Server::SyncRequestThreadManager : public ThreadManager { +class Server::SyncRequestThreadManager : public grpc::ThreadManager { public: - SyncRequestThreadManager(Server* server, CompletionQueue* server_cq, + SyncRequestThreadManager(Server* server, grpc::CompletionQueue* server_cq, std::shared_ptr global_callbacks, grpc_resource_quota* rq, int min_pollers, int max_pollers, int cq_timeout_msec) @@ -651,11 +828,11 @@ class Server::SyncRequestThreadManager : public ThreadManager { gpr_time_from_millis(cq_timeout_msec_, GPR_TIMESPAN)); switch (server_cq_->AsyncNext(tag, ok, deadline)) { - case CompletionQueue::TIMEOUT: + case grpc::CompletionQueue::TIMEOUT: return TIMEOUT; - case CompletionQueue::SHUTDOWN: + case grpc::CompletionQueue::SHUTDOWN: return SHUTDOWN; - case CompletionQueue::GOT_EVENT: + case grpc::CompletionQueue::GOT_EVENT: return WORK_FOUND; } @@ -690,15 +867,15 @@ class Server::SyncRequestThreadManager : public ThreadManager { // object } - void AddSyncMethod(internal::RpcServiceMethod* method, void* tag) { + void AddSyncMethod(grpc::internal::RpcServiceMethod* method, void* tag) { sync_requests_.emplace_back(new SyncRequest(method, tag)); } void AddUnknownSyncMethod() { if (!sync_requests_.empty()) { - unknown_method_.reset(new internal::RpcServiceMethod( - "unknown", internal::RpcMethod::BIDI_STREAMING, - new internal::UnknownMethodHandler)); + unknown_method_.reset(new grpc::internal::RpcServiceMethod( + "unknown", grpc::internal::RpcMethod::BIDI_STREAMING, + new grpc::internal::UnknownMethodHandler)); sync_requests_.emplace_back( new SyncRequest(unknown_method_.get(), nullptr)); } @@ -742,22 +919,22 @@ class Server::SyncRequestThreadManager : public ThreadManager { private: Server* server_; - CompletionQueue* server_cq_; + grpc::CompletionQueue* server_cq_; int cq_timeout_msec_; std::vector> sync_requests_; - std::unique_ptr unknown_method_; + std::unique_ptr unknown_method_; std::shared_ptr global_callbacks_; }; -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; Server::Server( - int max_receive_message_size, ChannelArguments* args, - std::shared_ptr>> + int max_receive_message_size, grpc::ChannelArguments* args, + std::shared_ptr>> sync_server_cqs, int min_pollers, int max_pollers, int sync_cq_timeout_msec, grpc_resource_quota* server_rq, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) : interceptor_creators_(std::move(interceptor_creators)), max_receive_message_size_(max_receive_message_size), @@ -769,8 +946,8 @@ Server::Server( server_initializer_(new grpc_impl::ServerInitializer(this)), health_check_service_disabled_(false) { g_gli_initializer.summon(); - gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); - global_callbacks_ = g_callbacks; + gpr_once_init(&grpc::g_once_init_callbacks, grpc::InitGlobalCallbacks); + global_callbacks_ = grpc::g_callbacks; global_callbacks_->UpdateArguments(args); if (sync_server_cqs_ != nullptr) { @@ -797,13 +974,14 @@ Server::Server( args->SetChannelArgs(&channel_args); for (size_t i = 0; i < channel_args.num_args; i++) { - if (0 == - strcmp(channel_args.args[i].key, kHealthCheckServiceInterfaceArg)) { + if (0 == strcmp(channel_args.args[i].key, + grpc::kHealthCheckServiceInterfaceArg)) { if (channel_args.args[i].value.pointer.p == nullptr) { health_check_service_disabled_ = true; } else { - health_check_service_.reset(static_cast( - channel_args.args[i].value.pointer.p)); + health_check_service_.reset( + static_cast( + channel_args.args[i].value.pointer.p)); } break; } @@ -840,49 +1018,49 @@ Server::~Server() { } void Server::SetGlobalCallbacks(GlobalCallbacks* callbacks) { - GPR_ASSERT(!g_callbacks); + GPR_ASSERT(!grpc::g_callbacks); GPR_ASSERT(callbacks); - g_callbacks.reset(callbacks); + grpc::g_callbacks.reset(callbacks); } grpc_server* Server::c_server() { return server_; } -std::shared_ptr Server::InProcessChannel( - const ChannelArguments& args) { +std::shared_ptr Server::InProcessChannel( + const grpc::ChannelArguments& args) { grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( + return grpc::CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr), - std::vector< - std::unique_ptr>()); + std::vector>()); } -std::shared_ptr +std::shared_ptr Server::experimental_type::InProcessChannelWithInterceptors( - const ChannelArguments& args, + const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args = args.c_channel_args(); - return CreateChannelInternal( + return grpc::CreateChannelInternal( "inproc", grpc_inproc_channel_create(server_->server_, &channel_args, nullptr), std::move(interceptor_creators)); } static grpc_server_register_method_payload_handling PayloadHandlingForMethod( - internal::RpcServiceMethod* method) { + grpc::internal::RpcServiceMethod* method) { switch (method->method_type()) { - case internal::RpcMethod::NORMAL_RPC: - case internal::RpcMethod::SERVER_STREAMING: + case grpc::internal::RpcMethod::NORMAL_RPC: + case grpc::internal::RpcMethod::SERVER_STREAMING: return GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER; - case internal::RpcMethod::CLIENT_STREAMING: - case internal::RpcMethod::BIDI_STREAMING: + case grpc::internal::RpcMethod::CLIENT_STREAMING: + case grpc::internal::RpcMethod::BIDI_STREAMING: return GRPC_SRM_PAYLOAD_NONE; } GPR_UNREACHABLE_CODE(return GRPC_SRM_PAYLOAD_NONE;); } -bool Server::RegisterService(const grpc::string* host, Service* service) { +bool Server::RegisterService(const grpc::string* host, grpc::Service* service) { bool has_async_methods = service->has_async_methods(); if (has_async_methods) { GPR_ASSERT(service->server_ == nullptr && @@ -898,7 +1076,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { continue; } - internal::RpcServiceMethod* method = it->get(); + grpc::internal::RpcServiceMethod* method = it->get(); void* method_registration_tag = grpc_server_register_method( server_, method->name(), host ? host->c_str() : nullptr, PayloadHandlingForMethod(method), 0); @@ -911,7 +1089,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { if (method->handler() == nullptr) { // Async method without handler method->set_server_tag(method_registration_tag); } else if (method->api_type() == - internal::RpcServiceMethod::ApiType::SYNC) { + grpc::internal::RpcServiceMethod::ApiType::SYNC) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->AddSyncMethod(method, method_registration_tag); } @@ -921,8 +1099,9 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { auto method_index = callback_unmatched_reqs_count_.size() - 1; // TODO(vjpai): Register these dynamically based on need for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { - callback_reqs_to_start_.push_back(new CallbackRequest( - this, method_index, method, method_registration_tag)); + callback_reqs_to_start_.push_back( + new CallbackRequest(this, method_index, method, + method_registration_tag)); } // Enqueue it so that it will be Request'ed later after all request // matchers are created at core server startup @@ -943,7 +1122,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { return true; } -void Server::RegisterAsyncGenericService(AsyncGenericService* service) { +void Server::RegisterAsyncGenericService(grpc::AsyncGenericService* service) { GPR_ASSERT(service->server_ == nullptr && "Can only register an async generic service against one server."); service->server_ = this; @@ -951,7 +1130,7 @@ void Server::RegisterAsyncGenericService(AsyncGenericService* service) { } void Server::RegisterCallbackGenericService( - experimental::CallbackGenericService* service) { + grpc::experimental::CallbackGenericService* service) { GPR_ASSERT( service->server_ == nullptr && "Can only register a callback generic service against one server."); @@ -963,44 +1142,45 @@ void Server::RegisterCallbackGenericService( auto method_index = callback_unmatched_reqs_count_.size() - 1; // TODO(vjpai): Register these dynamically based on need for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) { - callback_reqs_to_start_.push_back(new CallbackRequest( - this, method_index, nullptr, nullptr)); + callback_reqs_to_start_.push_back( + new CallbackRequest(this, method_index, + nullptr, nullptr)); } } int Server::AddListeningPort(const grpc::string& addr, - ServerCredentials* creds) { + grpc::ServerCredentials* creds) { GPR_ASSERT(!started_); int port = creds->AddPortToServer(addr, server_); global_callbacks_->AddPort(this, addr, creds, port); return port; } -void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { +void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) { GPR_ASSERT(!started_); global_callbacks_->PreServerStart(this); started_ = true; // Only create default health check service when user did not provide an // explicit one. - ServerCompletionQueue* health_check_cq = nullptr; - DefaultHealthCheckService::HealthCheckServiceImpl* + grpc::ServerCompletionQueue* health_check_cq = nullptr; + grpc::DefaultHealthCheckService::HealthCheckServiceImpl* default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && - DefaultHealthCheckServiceEnabled()) { - auto* default_hc_service = new DefaultHealthCheckService; + grpc::DefaultHealthCheckServiceEnabled()) { + auto* default_hc_service = new grpc::DefaultHealthCheckService; health_check_service_.reset(default_hc_service); // We create a non-polling CQ to avoid impacting application // performance. This ensures that we don't introduce thread hops // for application requests that wind up on this CQ, which is polled // in its own thread. - health_check_cq = - new ServerCompletionQueue(GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr); + health_check_cq = new grpc::ServerCompletionQueue( + GRPC_CQ_NEXT, GRPC_CQ_NON_POLLING, nullptr); grpc_server_register_completion_queue(server_, health_check_cq->cq(), nullptr); default_health_check_service_impl = default_hc_service->GetHealthCheckService( - std::unique_ptr(health_check_cq)); + std::unique_ptr(health_check_cq)); RegisterService(nullptr, default_health_check_service_impl); } @@ -1008,7 +1188,8 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // service to handle any unimplemented methods using the default reactor // creator if (!callback_reqs_to_start_.empty() && !has_callback_generic_service_) { - unimplemented_service_.reset(new experimental::CallbackGenericService); + unimplemented_service_.reset( + new grpc::experimental::CallbackGenericService); RegisterCallbackGenericService(unimplemented_service_.get()); } @@ -1033,7 +1214,8 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // server CQs), make sure that we have a ResourceExhausted handler // to deal with the case of thread exhaustion if (sync_server_cqs_ != nullptr && !sync_server_cqs_->empty()) { - resource_exhausted_handler_.reset(new internal::ResourceExhaustedHandler); + resource_exhausted_handler_.reset( + new grpc::internal::ResourceExhaustedHandler); } for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { @@ -1059,20 +1241,20 @@ void Server::ShutdownInternal(gpr_timespec deadline) { shutdown_ = true; /// The completion queue to use for server shutdown completion notification - CompletionQueue shutdown_cq; - ShutdownTag shutdown_tag; // Dummy shutdown tag + grpc::CompletionQueue shutdown_cq; + grpc::ShutdownTag shutdown_tag; // Dummy shutdown tag grpc_server_shutdown_and_notify(server_, shutdown_cq.cq(), &shutdown_tag); shutdown_cq.Shutdown(); void* tag; bool ok; - CompletionQueue::NextStatus status = + grpc::CompletionQueue::NextStatus status = shutdown_cq.AsyncNext(&tag, &ok, deadline); // If this timed out, it means we are done with the grace period for a clean // shutdown. We should force a shutdown now by cancelling all inflight calls - if (status == CompletionQueue::NextStatus::TIMEOUT) { + if (status == grpc::CompletionQueue::NextStatus::TIMEOUT) { grpc_server_cancel_all_calls(server_); } // Else in case of SHUTDOWN or GOT_EVENT, it means that the server has @@ -1124,154 +1306,11 @@ void Server::Wait() { } } -void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops, - internal::Call* call) { +void Server::PerformOpsOnCall(grpc::internal::CallOpSetInterface* ops, + grpc::internal::Call* call) { ops->FillOps(call); } -ServerInterface::BaseAsyncRequest::BaseAsyncRequest( - ServerInterface* server, ServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize) - : server_(server), - context_(context), - stream_(stream), - call_cq_(call_cq), - notification_cq_(notification_cq), - tag_(tag), - delete_on_finalize_(delete_on_finalize), - call_(nullptr), - done_intercepting_(false) { - /* Set up interception state partially for the receive ops. call_wrapper_ is - * not filled at this point, but it will be filled before the interceptors are - * run. */ - interceptor_methods_.SetCall(&call_wrapper_); - interceptor_methods_.SetReverse(); - call_cq_->RegisterAvalanching(); // This op will trigger more ops -} - -ServerInterface::BaseAsyncRequest::~BaseAsyncRequest() { - call_cq_->CompleteAvalanching(); -} - -bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag, - bool* status) { - if (done_intercepting_) { - *tag = tag_; - if (delete_on_finalize_) { - delete this; - } - return true; - } - context_->set_call(call_); - context_->cq_ = call_cq_; - if (call_wrapper_.call() == nullptr) { - // Fill it since it is empty. - call_wrapper_ = internal::Call( - call_, server_, call_cq_, server_->max_receive_message_size(), nullptr); - } - - // just the pointers inside call are copied here - stream_->BindCall(&call_wrapper_); - - if (*status && call_ && call_wrapper_.server_rpc_info()) { - done_intercepting_ = true; - // Set interception point for RECV INITIAL METADATA - interceptor_methods_.AddInterceptionHookPoint( - experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA); - interceptor_methods_.SetRecvInitialMetadata(&context_->client_metadata_); - if (interceptor_methods_.RunInterceptors( - [this]() { ContinueFinalizeResultAfterInterception(); })) { - // There are no interceptors to run. Continue - } else { - // There were interceptors to be run, so - // ContinueFinalizeResultAfterInterception will be run when interceptors - // are done. - return false; - } - } - if (*status && call_) { - context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); - } - *tag = tag_; - if (delete_on_finalize_) { - delete this; - } - return true; -} - -void ServerInterface::BaseAsyncRequest:: - ContinueFinalizeResultAfterInterception() { - context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr); - // Queue a tag which will be returned immediately - grpc_core::ExecCtx exec_ctx; - grpc_cq_begin_op(notification_cq_->cq(), this); - grpc_cq_end_op( - notification_cq_->cq(), this, GRPC_ERROR_NONE, - [](void* arg, grpc_cq_completion* completion) { delete completion; }, - nullptr, new grpc_cq_completion()); -} - -ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest( - ServerInterface* server, ServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, const char* name, - internal::RpcMethod::RpcType type) - : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag, - true), - name_(name), - type_(type) {} - -void ServerInterface::RegisteredAsyncRequest::IssueRequest( - void* registered_method, grpc_byte_buffer** payload, - ServerCompletionQueue* notification_cq) { - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_registered_call( - server_->server(), registered_method, &call_, - &context_->deadline_, - context_->client_metadata_.arr(), payload, - call_cq_->cq(), notification_cq->cq(), this)); -} - -ServerInterface::GenericAsyncRequest::GenericAsyncRequest( - ServerInterface* server, GenericServerContext* context, - internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq, - ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize) - : BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag, - delete_on_finalize) { - grpc_call_details_init(&call_details_); - GPR_ASSERT(notification_cq); - GPR_ASSERT(call_cq); - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( - server->server(), &call_, &call_details_, - context->client_metadata_.arr(), call_cq->cq(), - notification_cq->cq(), this)); -} - -bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag, - bool* status) { - // If we are done intercepting, there is nothing more for us to do - if (done_intercepting_) { - return BaseAsyncRequest::FinalizeResult(tag, status); - } - // TODO(yangg) remove the copy here. - if (*status) { - static_cast(context_)->method_ = - StringFromCopiedSlice(call_details_.method); - static_cast(context_)->host_ = - StringFromCopiedSlice(call_details_.host); - context_->deadline_ = call_details_.deadline; - } - grpc_slice_unref(call_details_.method); - grpc_slice_unref(call_details_.host); - call_wrapper_ = internal::Call( - call_, server_, call_cq_, server_->max_receive_message_size(), - context_->set_server_rpc_info( - static_cast(context_)->method_.c_str(), - internal::RpcMethod::BIDI_STREAMING, - *server_->interceptor_creators())); - return BaseAsyncRequest::FinalizeResult(tag, status); -} - bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag, bool* status) { if (GenericAsyncRequest::FinalizeResult(tag, status)) { @@ -1291,41 +1330,22 @@ bool Server::UnimplementedAsyncRequest::FinalizeResult(void** tag, Server::UnimplementedAsyncResponse::UnimplementedAsyncResponse( UnimplementedAsyncRequest* request) : request_(request) { - Status status(StatusCode::UNIMPLEMENTED, ""); - internal::UnknownMethodHandler::FillOps(request_->context(), this); + grpc::Status status(grpc::StatusCode::UNIMPLEMENTED, ""); + grpc::internal::UnknownMethodHandler::FillOps(request_->context(), this); request_->stream()->call_.PerformOps(this); } -ServerInitializer* Server::initializer() { return server_initializer_.get(); } - -namespace { -class ShutdownCallback : public grpc_experimental_completion_queue_functor { - public: - ShutdownCallback() { functor_run = &ShutdownCallback::Run; } - // TakeCQ takes ownership of the cq into the shutdown callback - // so that the shutdown callback will be responsible for destroying it - void TakeCQ(CompletionQueue* cq) { cq_ = cq; } - - // The Run function will get invoked by the completion queue library - // when the shutdown is actually complete - static void Run(grpc_experimental_completion_queue_functor* cb, int) { - auto* callback = static_cast(cb); - delete callback->cq_; - delete callback; - } - - private: - CompletionQueue* cq_ = nullptr; -}; -} // namespace +grpc::ServerInitializer* Server::initializer() { + return server_initializer_.get(); +} -CompletionQueue* Server::CallbackCQ() { +grpc::CompletionQueue* Server::CallbackCQ() { // TODO(vjpai): Consider using a single global CQ for the default CQ // if there is no explicit per-server CQ registered grpc::internal::MutexLock l(&mu_); if (callback_cq_ == nullptr) { - auto* shutdown_callback = new ShutdownCallback; - callback_cq_ = new CompletionQueue(grpc_completion_queue_attributes{ + auto* shutdown_callback = new grpc::ShutdownCallback; + callback_cq_ = new grpc::CompletionQueue(grpc_completion_queue_attributes{ GRPC_CQ_CURRENT_VERSION, GRPC_CQ_CALLBACK, GRPC_CQ_DEFAULT_POLLING, shutdown_callback}); @@ -1335,4 +1355,4 @@ CompletionQueue* Server::CallbackCQ() { return callback_cq_; } -} // namespace grpc +} // namespace grpc_impl diff --git a/test/cpp/util/metrics_server.h b/test/cpp/util/metrics_server.h index 2d6ddf08043..08f6034c28e 100644 --- a/test/cpp/util/metrics_server.h +++ b/test/cpp/util/metrics_server.h @@ -21,6 +21,8 @@ #include #include +#include + #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index a0a6e952409..67bbb4efa6b 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1013,6 +1013,7 @@ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 21e5b49440f..438cb98dbae 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1015,6 +1015,7 @@ include/grpcpp/server.h \ include/grpcpp/server_builder.h \ include/grpcpp/server_builder_impl.h \ include/grpcpp/server_context.h \ +include/grpcpp/server_impl.h \ include/grpcpp/server_posix.h \ include/grpcpp/server_posix_impl.h \ include/grpcpp/support/async_stream.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 29372824822..8534e71e2ce 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10152,6 +10152,7 @@ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", @@ -10272,6 +10273,7 @@ "include/grpcpp/server_builder.h", "include/grpcpp/server_builder_impl.h", "include/grpcpp/server_context.h", + "include/grpcpp/server_impl.h", "include/grpcpp/server_posix.h", "include/grpcpp/server_posix_impl.h", "include/grpcpp/support/async_stream.h", From f370542dd6ea8cf53540abe19eb1659592cae712 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Sat, 13 Apr 2019 14:34:21 -0600 Subject: [PATCH 017/112] Add BadStatus#to_rpc_status --- src/ruby/lib/grpc/errors.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 0c15c2f3bac..236bd9e26f7 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -13,6 +13,7 @@ # limitations under the License. require_relative './grpc' +require_relative './google_rpc_status_utils' # GRPC contains the General RPC module. module GRPC @@ -47,7 +48,20 @@ module GRPC # # @return [Status] with the same code and details def to_status - Struct::Status.new(code, details, @metadata) + Struct::Status.new(code, details, metadata) + end + + # Converts the exception to a deserialized Google::Rpc::Status proto. + # Returns nil if the `grpc-status-details-bin` trailer could not be + # converted to a {Google::Rpc::Status} due to the server not providing + # the necessary trailers. + # + # Raises an error if the server did provide the necessary trailers + # but they fail to deserialize into a {Google::Rpc::Status} protobuf. + # + # @return [Google::Rpc::Status] with the same code and details + def to_rpc_status + GoogleRpcStatusUtils.extract_google_rpc_status to_status end def self.new_status_exception(code, details = 'unknown cause', From 7afc6dbae31860670aa751e865fb85de7316df5f Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 03:00:33 -0600 Subject: [PATCH 018/112] Update BadStatus#to_rpc_status Change the implementation to no longer raise when the rpc_status protobuf value cannot be properly decoded. Update the documentation. --- src/ruby/lib/grpc/errors.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 236bd9e26f7..2075e91560c 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -51,17 +51,20 @@ module GRPC Struct::Status.new(code, details, metadata) end - # Converts the exception to a deserialized Google::Rpc::Status proto. - # Returns nil if the `grpc-status-details-bin` trailer could not be + # Converts the exception to a deserialized {Google::Rpc::Status} object. + # Returns `nil` if the `grpc-status-details-bin` trailer could not be # converted to a {Google::Rpc::Status} due to the server not providing # the necessary trailers. # - # Raises an error if the server did provide the necessary trailers - # but they fail to deserialize into a {Google::Rpc::Status} protobuf. - # - # @return [Google::Rpc::Status] with the same code and details + # @return [Google::Rpc::Status, nil] def to_rpc_status - GoogleRpcStatusUtils.extract_google_rpc_status to_status + status = to_status + + return if status.nil? + + GoogleRpcStatusUtils.extract_google_rpc_status(status) + rescue + nil end def self.new_status_exception(code, details = 'unknown cause', From 71db662452a3d1881cf003389c09f7c8cd9aead7 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 03:01:28 -0600 Subject: [PATCH 019/112] Add tests for error methods --- src/ruby/spec/errors_spec.rb | 132 +++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 src/ruby/spec/errors_spec.rb diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb new file mode 100644 index 00000000000..7469ee982a2 --- /dev/null +++ b/src/ruby/spec/errors_spec.rb @@ -0,0 +1,132 @@ +# Copyright 2019 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +require 'spec_helper' +require 'google/protobuf/well_known_types' +require_relative '../pb/src/proto/grpc/testing/messages_pb' + +describe GRPC::BadStatus do + describe :attributes do + it 'has attributes' do + code = 1 + details = 'details' + metadata = { 'key' => 'val' } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.code).to eq code + expect(exception.details).to eq details + expect(exception.metadata).to eq metadata + end + end + + describe :new_status_exception do + let(:codes_and_classes) do + [ + [GRPC::Core::StatusCodes::OK, GRPC::Ok], + [GRPC::Core::StatusCodes::CANCELLED, GRPC::Cancelled], + [GRPC::Core::StatusCodes::UNKNOWN, GRPC::Unknown], + [GRPC::Core::StatusCodes::INVALID_ARGUMENT, GRPC::InvalidArgument], + [GRPC::Core::StatusCodes::DEADLINE_EXCEEDED, GRPC::DeadlineExceeded], + [GRPC::Core::StatusCodes::NOT_FOUND, GRPC::NotFound], + [GRPC::Core::StatusCodes::ALREADY_EXISTS, GRPC::AlreadyExists], + [GRPC::Core::StatusCodes::PERMISSION_DENIED, GRPC::PermissionDenied], + [GRPC::Core::StatusCodes::UNAUTHENTICATED, GRPC::Unauthenticated], + [GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, GRPC::ResourceExhausted], + [GRPC::Core::StatusCodes::FAILED_PRECONDITION, GRPC::FailedPrecondition], + [GRPC::Core::StatusCodes::ABORTED, GRPC::Aborted], + [GRPC::Core::StatusCodes::OUT_OF_RANGE, GRPC::OutOfRange], + [GRPC::Core::StatusCodes::UNIMPLEMENTED, GRPC::Unimplemented], + [GRPC::Core::StatusCodes::INTERNAL, GRPC::Internal], + [GRPC::Core::StatusCodes::UNAVAILABLE, GRPC::Unavailable], + [GRPC::Core::StatusCodes::DATA_LOSS, GRPC::DataLoss], + [99, GRPC::BadStatus] # Unknown codes default to BadStatus + ] + end + + it 'maps codes to the correct error class' do + codes_and_classes.each do |code, grpc_error_class| + exception = GRPC::BadStatus.new_status_exception(code) + + expect(exception).to be_a grpc_error_class + end + end + end + + describe :to_status do + it 'gets status' do + code = 1 + details = 'details' + metadata = { 'key' => 'val' } + + exception = GRPC::BadStatus.new(code, details, metadata) + status = Struct::Status.new(code, details, metadata) + + expect(exception.to_status).to eq status + end + end + + describe :to_rpc_status do + let(:simple_request_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack( + Grpc::Testing::SimpleRequest.new( + payload: Grpc::Testing::Payload.new(body: 'request') + ) + ) + end + end + let(:simple_response_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack( + Grpc::Testing::SimpleResponse.new( + payload: Grpc::Testing::Payload.new(body: 'response') + ) + ) + end + end + let(:payload_any) do + Google::Protobuf::Any.new.tap do |any| + any.pack(Grpc::Testing::Payload.new(body: 'payload')) + end + end + + it 'decodes proto values' do + rpc_status = Google::Rpc::Status.new( + code: 1, + message: 'matching message', + details: [simple_request_any, simple_response_any, payload_any] + ) + rpc_status_proto = Google::Rpc::Status.encode(rpc_status) + + code = 1 + details = 'details' + metadata = { 'grpc-status-details-bin' => rpc_status_proto } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.to_rpc_status).to eq rpc_status + end + + it 'does not raise when decoding a bad proto' do + code = 1 + details = 'details' + metadata = { 'grpc-status-details-bin' => 'notavalidprotostream' } + + exception = GRPC::BadStatus.new(code, details, metadata) + + expect(exception.to_rpc_status).to be nil + end + end +end From 0fa7cf9194dc0e74cbdc30e33da106cc778ff0e4 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 03:02:31 -0600 Subject: [PATCH 020/112] Update Add BadStatus#to_status documentation --- src/ruby/lib/grpc/errors.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 2075e91560c..148f0dadb6f 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -43,10 +43,10 @@ module GRPC @metadata = metadata end - # Converts the exception to a GRPC::Status for use in the networking + # Converts the exception to a {Struct::Status} for use in the networking # wrapper layer. # - # @return [Status] with the same code and details + # @return [Struct::Status] with the same code and details def to_status Struct::Status.new(code, details, metadata) end From 41871bf7de69cf601378178d28e117ffab5470a3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 18 Apr 2019 17:01:45 -0700 Subject: [PATCH 021/112] Add cares glue for libuv event loop --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 4 + Makefile | 4 + build.yaml | 2 + config.m4 | 2 + config.w32 | 2 + gRPC-Core.podspec | 2 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../resolver/dns/c_ares/dns_resolver_ares.cc | 6 +- .../dns/c_ares/grpc_ares_ev_driver.cc | 6 +- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 134 ++++++++++++++++++ .../resolver/dns/c_ares/grpc_ares_wrapper.cc | 4 +- .../dns/c_ares/grpc_ares_wrapper_fallback.cc | 4 +- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 103 ++++++++++++++ src/python/grpcio/grpc_core_dependencies.py | 2 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 2 + 20 files changed, 282 insertions(+), 9 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc diff --git a/BUILD b/BUILD index 0bcfc293be3..58f0855961e 100644 --- a/BUILD +++ b/BUILD @@ -1552,10 +1552,12 @@ grpc_cc_library( srcs = [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", ], diff --git a/BUILD.gn b/BUILD.gn index 1417f1db5ea..a188ed86ac3 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -309,11 +309,13 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b99a57633a..dd32088e97f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1281,10 +1281,12 @@ add_library(grpc src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -2650,10 +2652,12 @@ add_library(grpc_unsecure src/core/ext/transport/inproc/inproc_transport.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc diff --git a/Makefile b/Makefile index 2e6e6070c43..b1dcc82c601 100644 --- a/Makefile +++ b/Makefile @@ -3736,10 +3736,12 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ @@ -5053,10 +5055,12 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/inproc/inproc_transport.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ diff --git a/build.yaml b/build.yaml index 5e8c803e56f..48c45eb799d 100644 --- a/build.yaml +++ b/build.yaml @@ -781,10 +781,12 @@ filegroups: src: - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc plugin: grpc_resolver_dns_ares diff --git a/config.m4 b/config.m4 index 2c64a3eb168..e255602a48d 100644 --- a/config.m4 +++ b/config.m4 @@ -396,10 +396,12 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ diff --git a/config.w32 b/config.w32 index 6897c1041ac..e83b3e3dd7f 100644 --- a/config.w32 +++ b/config.w32 @@ -371,10 +371,12 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_libuv.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index bab7ce4378e..4a2ea853f29 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -843,10 +843,12 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', diff --git a/grpc.gemspec b/grpc.gemspec index b9d2107ee48..b7e0d54eaab 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -780,10 +780,12 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) diff --git a/grpc.gyp b/grpc.gyp index 322259d2ca7..19427da3ca6 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -578,10 +578,12 @@ 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -1317,10 +1319,12 @@ 'src/core/ext/transport/inproc/inproc_transport.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', diff --git a/package.xml b/package.xml index f3bbb449ac5..26cc17756e8 100644 --- a/package.xml +++ b/package.xml @@ -785,10 +785,12 @@ + + diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 7b5eb311393..3f1a700c3d6 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -18,7 +18,7 @@ #include -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include #include @@ -464,10 +464,10 @@ void grpc_resolver_dns_ares_shutdown() { gpr_free(resolver_env); } -#else /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#else /* GRPC_ARES == 1 */ void grpc_resolver_dns_ares_init(void) {} void grpc_resolver_dns_ares_shutdown(void) {} -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc index d99c2e30047..9fff92da52f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -18,7 +18,7 @@ #include #include "src/core/lib/iomgr/port.h" -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include #include @@ -218,6 +218,7 @@ static void on_timeout_locked(void* arg, grpc_error* error) { static void on_readable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); + GPR_ASSERT(fdn->readable_registered); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->readable_registered = false; @@ -242,6 +243,7 @@ static void on_readable_locked(void* arg, grpc_error* error) { static void on_writable_locked(void* arg, grpc_error* error) { fd_node* fdn = static_cast(arg); + GPR_ASSERT(fdn->writable_registered); grpc_ares_ev_driver* ev_driver = fdn->ev_driver; const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked(); fdn->writable_registered = false; @@ -365,4 +367,4 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) { } } -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc new file mode 100644 index 00000000000..5831056dde8 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -0,0 +1,134 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && defined(GRPC_UV) + +#include +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" + +#include +#include +#include +#include +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/lib/gpr/string.h" + +namespace grpc_core { + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); + +void ares_uv_poll_close_cb(uv_handle_t *handle) { + delete handle; +} + +class GrpcPolledFdLibuv : public GrpcPolledFd { + public: + GrpcPolledFdLibuv(ares_socket_t as): as_(as) { + gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); + handle_ = new uv_poll_t; + uv_poll_init_socket(uv_default_loop(), handle_, as); + handle_->data = this; + } + + ~GrpcPolledFdLibuv() { + gpr_free(name_); + } + + void RegisterForOnReadableLocked(grpc_closure* read_closure) override { + GPR_ASSERT(read_closure_ == nullptr); + GPR_ASSERT((poll_events_ & UV_READABLE) == 0); + read_closure_ = read_closure; + poll_events_ |= UV_READABLE; + uv_poll_start(handle_, poll_events_, ares_uv_poll_cb); + } + + void RegisterForOnWriteableLocked(grpc_closure* write_closure) override { + GPR_ASSERT(write_closure_ == nullptr); + GPR_ASSERT((poll_events_ & UV_WRITABLE) == 0); + write_closure_ = write_closure; + poll_events_ |= UV_WRITABLE; + uv_poll_start(handle_, poll_events_, ares_uv_poll_cb); + } + + bool IsFdStillReadableLocked() override { + /* uv_poll_t is based on poll, which is level triggered. So, if cares + * leaves some data unread, the event will trigger again. */ + return false; + } + + void ShutdownLocked(grpc_error* error) override { + uv_poll_stop(handle_); + uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); + } + + ares_socket_t GetWrappedAresSocketLocked() override { return as_; } + + const char* GetName() override { return name_; } + + char* name_; + ares_socket_t as_; + uv_poll_t* handle_; + grpc_closure* read_closure_ = nullptr; + grpc_closure* write_closure_ = nullptr; + int poll_events_ = 0; +}; + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { + grpc_core::ExecCtx exec_ctx; + GrpcPolledFdLibuv* polled_fd = reinterpret_cast(handle->data); + grpc_error *error = GRPC_ERROR_NONE; + if (status < 0) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); + error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, + grpc_slice_from_static_string(uv_strerror(status))); + } + if ((events & UV_READABLE) && polled_fd->read_closure_) { + GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); + polled_fd->read_closure_ = nullptr; + polled_fd->poll_events_ &= ~UV_READABLE; + } + if ((events & UV_WRITABLE) && polled_fd->write_closure_) { + GRPC_CLOSURE_SCHED(polled_fd->write_closure_, error); + polled_fd->write_closure_ = nullptr; + polled_fd->poll_events_ &= ~UV_WRITABLE; + } + uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); +} + +class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { + public: + GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as, + grpc_pollset_set* driver_pollset_set, + grpc_combiner* combiner) override { + return New(as); + } + + void ConfigureAresChannelLocked(ares_channel channel) override {} +}; + +UniquePtr NewGrpcPolledFdFactory(grpc_combiner* combiner) { + return UniquePtr(New()); +} + +} // namespace grpc_core + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 37b0b365eed..97ef61d2f33 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -18,7 +18,7 @@ #include -#if GRPC_ARES == 1 && !defined(GRPC_UV) +#if GRPC_ARES == 1 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/iomgr/sockaddr.h" @@ -687,4 +687,4 @@ void (*grpc_resolve_address_ares)( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl; -#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */ +#endif /* GRPC_ARES == 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index 1f4701c9994..d2de88eaa1e 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -18,7 +18,7 @@ #include -#if GRPC_ARES != 1 || defined(GRPC_UV) +#if GRPC_ARES != 1 #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" @@ -62,4 +62,4 @@ void (*grpc_resolve_address_ares)( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_resolved_addresses** addrs) = grpc_resolve_address_ares_impl; -#endif /* GRPC_ARES != 1 || defined(GRPC_UV) */ +#endif /* GRPC_ARES != 1 */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc new file mode 100644 index 00000000000..eb8d7e5e900 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -0,0 +1,103 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && defined(GRPC_UV) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool grpc_ares_query_ipv6() { + /* The libuv grpc code currently does not have the code to probe for this, + * so we assume for nowthat IPv6 is always available in contexts where this + * code will be used. */ + return true; +} + +/* The following two functions were copied entirely from the Windows file. This + * code can run on Windows so it can have the same problem. */ +static bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during Windows localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during Windows localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} + +bool grpc_ares_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs) { + char* host = nullptr; + char* port = nullptr; + bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port, + addrs, &host, &port); + gpr_free(host); + gpr_free(port); + return out; +} + +#endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 21efd682871..9c375f5eb87 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -370,10 +370,12 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index e68e758c64e..a3869cd239c 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -942,11 +942,13 @@ src/core/ext/filters/client_channel/resolver/README.md \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 29fd6f32e59..52c69ad10b5 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9084,11 +9084,13 @@ "src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" ], From a84d188021c9f76905e6c211ff7b9e2af2d16345 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 18 Apr 2019 17:45:36 -0700 Subject: [PATCH 022/112] Don't use 'new' or 'delete' --- .../resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index 5831056dde8..fd09d899187 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -37,14 +37,14 @@ namespace grpc_core { void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); void ares_uv_poll_close_cb(uv_handle_t *handle) { - delete handle; + Delete(handle); } class GrpcPolledFdLibuv : public GrpcPolledFd { public: GrpcPolledFdLibuv(ares_socket_t as): as_(as) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); - handle_ = new uv_poll_t; + handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); handle_->data = this; } From b47f2048b8f321de3f4c4f1cd7e36e33407994ad Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Thu, 18 Apr 2019 22:26:39 -0600 Subject: [PATCH 023/112] Log ParseError raised in BadStatus#to_rpc_status --- src/ruby/lib/grpc/errors.rb | 4 +++- src/ruby/spec/errors_spec.rb | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb index 148f0dadb6f..83beb6a906a 100644 --- a/src/ruby/lib/grpc/errors.rb +++ b/src/ruby/lib/grpc/errors.rb @@ -63,7 +63,9 @@ module GRPC return if status.nil? GoogleRpcStatusUtils.extract_google_rpc_status(status) - rescue + rescue Google::Protobuf::ParseError => parse_error + GRPC.logger.warn('parse error: to_rpc_status failed') + GRPC.logger.warn(parse_error) nil end diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb index 7469ee982a2..30e897700b3 100644 --- a/src/ruby/spec/errors_spec.rb +++ b/src/ruby/spec/errors_spec.rb @@ -127,6 +127,14 @@ describe GRPC::BadStatus do exception = GRPC::BadStatus.new(code, details, metadata) expect(exception.to_rpc_status).to be nil + + # Check that the parse error was logged correctly + log_contents = @log_output.read + expected_line_1 = 'WARN GRPC : parse error: to_rpc_status failed' + expected_line_2 = 'WARN GRPC : ' \ + 'Error occurred during parsing: Invalid wire type' + expect(log_contents).to include expected_line_1 + expect(log_contents).to include expected_line_2 end end end From 813865acafe90a369a6986f87428af3344c1a1b9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 11 Apr 2019 17:46:12 -0700 Subject: [PATCH 024/112] Adding service config parser --- .../filters/client_channel/client_channel.cc | 102 ++-- .../client_channel/client_channel_plugin.cc | 6 + .../ext/filters/client_channel/lb_policy.cc | 32 +- .../ext/filters/client_channel/lb_policy.h | 26 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 93 +++- .../lb_policy/pick_first/pick_first.cc | 20 + .../lb_policy/round_robin/round_robin.cc | 20 + .../client_channel/lb_policy/xds/xds.cc | 176 ++++-- .../client_channel/lb_policy_factory.h | 14 +- .../client_channel/lb_policy_registry.cc | 24 + .../client_channel/lb_policy_registry.h | 3 + .../client_channel/resolver_result_parsing.cc | 500 ++++++++++++------ .../client_channel/resolver_result_parsing.h | 149 +++--- .../client_channel/resolving_lb_policy.cc | 13 +- .../client_channel/resolving_lb_policy.h | 15 +- .../filters/client_channel/service_config.cc | 29 +- .../filters/client_channel/service_config.h | 7 +- src/core/lib/channel/context.h | 2 + src/core/lib/gprpp/optional.h | 5 +- src/core/lib/iomgr/error.h | 1 + .../client_channel/service_config_test.cc | 61 ++- 21 files changed, 903 insertions(+), 395 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 049c8d0a13f..262795b025c 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -66,8 +66,7 @@ #include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/status_metadata.h" -using grpc_core::internal::ClientChannelMethodParams; -using grpc_core::internal::ClientChannelMethodParamsTable; +using grpc_core::internal::ClientChannelMethodParsedObject; using grpc_core::internal::ProcessedResolverResult; using grpc_core::internal::ServerRetryThrottleData; @@ -169,7 +168,6 @@ struct client_channel_channel_data { // Data from service config. bool received_service_config_data; grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params_table; grpc_core::RefCountedPtr service_config; // @@ -277,11 +275,9 @@ class ServiceConfigSetter { ServiceConfigSetter( channel_data* chand, RefCountedPtr retry_throttle_data, - RefCountedPtr method_params_table, RefCountedPtr service_config) : chand_(chand), retry_throttle_data_(std::move(retry_throttle_data)), - method_params_table_(std::move(method_params_table)), service_config_(std::move(service_config)) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "ServiceConfigSetter"); GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, @@ -296,7 +292,6 @@ class ServiceConfigSetter { // Update channel state. chand->received_service_config_data = true; chand->retry_throttle_data = std::move(self->retry_throttle_data_); - chand->method_params_table = std::move(self->method_params_table_); chand->service_config = std::move(self->service_config_); // Apply service config to queued picks. for (QueuedPick* pick = chand->queued_picks; pick != nullptr; @@ -310,7 +305,6 @@ class ServiceConfigSetter { channel_data* chand_; RefCountedPtr retry_throttle_data_; - RefCountedPtr method_params_table_; RefCountedPtr service_config_; grpc_closure closure_; }; @@ -497,20 +491,19 @@ class ClientChannelControlHelper // result update. static bool process_resolver_result_locked( void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name, - grpc_core::RefCountedPtr* lb_policy_config) { + const grpc_core::ParsedLoadBalancingConfig** lb_policy_config) { channel_data* chand = static_cast(arg); ProcessedResolverResult resolver_result(result, chand->enable_retries); - grpc_core::UniquePtr service_config_json = - resolver_result.service_config_json(); + const char* service_config_json = resolver_result.service_config_json(); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", - chand, service_config_json.get()); + chand, service_config_json); } // Create service config setter to update channel state in the data // plane combiner. Destroys itself when done. grpc_core::New( chand, resolver_result.retry_throttle_data(), - resolver_result.method_params_table(), resolver_result.service_config()); + resolver_result.service_config()); // Swap out the data used by cc_get_channel_info(). gpr_mu_lock(&chand->info_mu); chand->info_lb_policy_name = resolver_result.lb_policy_name(); @@ -518,9 +511,8 @@ static bool process_resolver_result_locked( ((service_config_json == nullptr) != (chand->info_service_config_json == nullptr)) || (service_config_json != nullptr && - strcmp(service_config_json.get(), - chand->info_service_config_json.get()) != 0); - chand->info_service_config_json = std::move(service_config_json); + strcmp(service_config_json, chand->info_service_config_json.get()) != 0); + chand->info_service_config_json.reset(gpr_strdup(service_config_json)); gpr_mu_unlock(&chand->info_mu); // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); @@ -749,7 +741,7 @@ static void cc_destroy_channel_elem(grpc_channel_element* elem) { chand->info_lb_policy_name.reset(); chand->info_service_config_json.reset(); chand->retry_throttle_data.reset(); - chand->method_params_table.reset(); + chand->service_config.reset(); grpc_client_channel_stop_backup_polling(chand->interested_parties); grpc_pollset_set_destroy(chand->interested_parties); GRPC_COMBINER_UNREF(chand->data_plane_combiner, "client_channel"); @@ -974,8 +966,8 @@ struct call_data { grpc_call_context_element* call_context; grpc_core::RefCountedPtr retry_throttle_data; - grpc_core::RefCountedPtr method_params; grpc_core::RefCountedPtr service_config; + ClientChannelMethodParsedObject* method_params = nullptr; grpc_core::RefCountedPtr subchannel_call; @@ -1474,8 +1466,7 @@ static void do_retry(grpc_call_element* elem, channel_data* chand = static_cast(elem->channel_data); call_data* calld = static_cast(elem->call_data); GPR_ASSERT(calld->method_params != nullptr); - const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + const auto* retry_policy = calld->method_params->retry_policy(); GPR_ASSERT(retry_policy != nullptr); // Reset subchannel call and connected subchannel. calld->subchannel_call.reset(); @@ -1520,8 +1511,7 @@ static bool maybe_retry(grpc_call_element* elem, call_data* calld = static_cast(elem->call_data); // Get retry policy. if (calld->method_params == nullptr) return false; - const ClientChannelMethodParams::RetryPolicy* retry_policy = - calld->method_params->retry_policy(); + const auto* retry_policy = calld->method_params->retry_policy(); if (retry_policy == nullptr) return false; // If we've already dispatched a retry from this call, return true. // This catches the case where the batch has multiple callbacks @@ -2819,46 +2809,50 @@ static void apply_service_config_to_call_locked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, calld); } - if(chand->service_config != nullptr) { + if (chand->service_config != nullptr) { calld->service_config = chand->service_config; calld->call_context[GRPC_SERVICE_CONFIG].value = &calld->service_config; + const auto* method_params_vector_ptr = + chand->service_config->GetMethodServiceConfigObjectsVector(calld->path); + if (method_params_vector_ptr != nullptr) { + calld->method_params = static_cast( + ((*method_params_vector_ptr) + [grpc_core::internal::ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index()]) + .get()); + calld->call_context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value = + const_cast( + method_params_vector_ptr); + } } if (chand->retry_throttle_data != nullptr) { calld->retry_throttle_data = chand->retry_throttle_data->Ref(); } - if (chand->method_params_table != nullptr) { - calld->method_params = grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand->method_params_table, calld->path); - if (calld->method_params != nullptr) { - // If the deadline from the service config is shorter than the one - // from the client API, reset the deadline timer. - if (chand->deadline_checking_enabled && - calld->method_params->timeout() != 0) { - const grpc_millis per_method_deadline = - grpc_timespec_to_millis_round_up(calld->call_start_time) + - calld->method_params->timeout(); - if (per_method_deadline < calld->deadline) { - calld->deadline = per_method_deadline; - grpc_deadline_state_reset(elem, calld->deadline); - } + if (calld->method_params != nullptr) { + // If the deadline from the service config is shorter than the one + // from the client API, reset the deadline timer. + if (chand->deadline_checking_enabled && + calld->method_params->timeout() != 0) { + const grpc_millis per_method_deadline = + grpc_timespec_to_millis_round_up(calld->call_start_time) + + calld->method_params->timeout(); + if (per_method_deadline < calld->deadline) { + calld->deadline = per_method_deadline; + grpc_deadline_state_reset(elem, calld->deadline); } - // If the service config set wait_for_ready and the application - // did not explicitly set it, use the value from the service config. - uint32_t* send_initial_metadata_flags = - &calld->pending_batches[0] - .batch->payload->send_initial_metadata - .send_initial_metadata_flags; - if (GPR_UNLIKELY( - calld->method_params->wait_for_ready() != - ClientChannelMethodParams::WAIT_FOR_READY_UNSET && - !(*send_initial_metadata_flags & - GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET))) { - if (calld->method_params->wait_for_ready() == - ClientChannelMethodParams::WAIT_FOR_READY_TRUE) { - *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } else { - *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; - } + } + // If the service config set wait_for_ready and the application + // did not explicitly set it, use the value from the service config. + uint32_t* send_initial_metadata_flags = + &calld->pending_batches[0] + .batch->payload->send_initial_metadata.send_initial_metadata_flags; + if (calld->method_params->wait_for_ready().has_value() && + !(*send_initial_metadata_flags & + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET)) { + if (calld->method_params->wait_for_ready().value()) { + *send_initial_metadata_flags |= GRPC_INITIAL_METADATA_WAIT_FOR_READY; + } else { + *send_initial_metadata_flags &= ~GRPC_INITIAL_METADATA_WAIT_FOR_READY; } } } diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 8e76c4cbb15..12f02fc49fb 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -32,6 +32,7 @@ #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" +#include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/lib/surface/channel_init.h" @@ -48,8 +49,13 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { builder, static_cast(arg), nullptr, nullptr); } +void grpc_service_config_register_parsers() { + grpc_core::internal::ClientChannelServiceConfigParser::Register(); +} + void grpc_client_channel_init(void) { grpc_core::ServiceConfig::Init(); + grpc_service_config_register_parsers(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 6b657465891..1cd5e6c9e98 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -63,28 +63,50 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, } grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( - const grpc_json* lb_config_array) { + const grpc_json* lb_config_array, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:type should be array"); return nullptr; } // Find the first LB policy that this client supports. for (const grpc_json* lb_config = lb_config_array->child; lb_config != nullptr; lb_config = lb_config->next) { - if (lb_config->type != GRPC_JSON_OBJECT) return nullptr; + if (lb_config->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:child entry should be of type " + "object"); + return nullptr; + } grpc_json* policy = nullptr; for (grpc_json* field = lb_config->child; field != nullptr; field = field->next) { - if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) + if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:child entry should be of type " + "object"); + return nullptr; + } + if (policy != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:oneOf violation"); return nullptr; - if (policy != nullptr) return nullptr; // Violate "oneof" type. + } // Violate "oneof" type. policy = field; } - if (policy == nullptr) return nullptr; + if (policy == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:no policy found in child entry"); + return nullptr; + } // If we support this policy, then select it. if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { return policy; } } + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:No known policy"); return nullptr; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 1c17f95423e..30e6dca1cd9 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -36,6 +36,8 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; namespace grpc_core { +class ParsedLoadBalancingConfig; + /// Interface for load balancing policies. /// /// The following concepts are used here: @@ -194,30 +196,11 @@ class LoadBalancingPolicy : public InternallyRefCounted { GRPC_ABSTRACT_BASE_CLASS }; - /// Configuration for an LB policy instance. - // TODO(roth): Find a better JSON representation for this API. - class Config : public RefCounted { - public: - Config(const grpc_json* lb_config, - RefCountedPtr service_config) - : json_(lb_config), service_config_(std::move(service_config)) {} - - const char* name() const { return json_->key; } - const grpc_json* config() const { return json_->child; } - RefCountedPtr service_config() const { - return service_config_; - } - - private: - const grpc_json* json_; - RefCountedPtr service_config_; - }; - /// Data passed to the UpdateLocked() method when new addresses and /// config are available. struct UpdateArgs { ServerAddressList addresses; - RefCountedPtr config; + const ParsedLoadBalancingConfig* config = nullptr; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is @@ -290,7 +273,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Returns the JSON node of policy (with both policy name and config content) /// given the JSON node of a LoadBalancingConfig array. - static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array); + static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array, + grpc_error** error); // A picker that returns PICK_QUEUE for all picks. // Also calls the parent LB policy's ExitIdleLocked() method when the diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ead15308f49..f8922bf7bcc 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -118,6 +118,23 @@ namespace { constexpr char kGrpclb[] = "grpclb"; +class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { + public: + ParsedGrpcLbConfig(UniquePtr child_policy, + const grpc_json* json) + : child_policy_(std::move(child_policy)), json_(json) {} + const char* name() const override { return kGrpclb; } + + const ParsedLoadBalancingConfig* child_policy() const { + return child_policy_.get(); + } + const grpc_json* config() const { return json_; } + + private: + UniquePtr child_policy_; + const grpc_json* json_ = nullptr; +}; + class GrpcLb : public LoadBalancingPolicy { public: explicit GrpcLb(Args args); @@ -302,7 +319,7 @@ class GrpcLb : public LoadBalancingPolicy { // Helper functions used in UpdateLocked(). void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, const grpc_channel_args& args); - void ParseLbConfig(Config* grpclb_config); + void ParseLbConfig(const ParsedGrpcLbConfig* grpclb_config); static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); void CancelBalancerChannelConnectivityWatchLocked(); @@ -380,7 +397,7 @@ class GrpcLb : public LoadBalancingPolicy { // until it reports READY, at which point it will be moved to child_policy_. OrphanablePtr pending_child_policy_; // The child policy config. - RefCountedPtr child_policy_config_; + const ParsedLoadBalancingConfig* child_policy_config_ = nullptr; // Child policy in state READY. bool child_policy_ready_ = false; }; @@ -1383,7 +1400,7 @@ void GrpcLb::FillChildRefsForChannelz( void GrpcLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_channel_ == nullptr; - ParseLbConfig(args.config.get()); + ParseLbConfig(static_cast(args.config)); ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); @@ -1472,24 +1489,11 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked( response_generator_->SetResponse(std::move(result)); } -void GrpcLb::ParseLbConfig(Config* grpclb_config) { - const grpc_json* child_policy = nullptr; +void GrpcLb::ParseLbConfig(const ParsedGrpcLbConfig* grpclb_config) { if (grpclb_config != nullptr) { - const grpc_json* grpclb_config_json = grpclb_config->config(); - for (const grpc_json* field = grpclb_config_json; field != nullptr; - field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "childPolicy") == 0) { - if (child_policy != nullptr) return; // Duplicate. - child_policy = ParseLoadBalancingConfig(field); - } - } - } - if (child_policy != nullptr) { - child_policy_config_ = - MakeRefCounted(child_policy, grpclb_config->service_config()); + child_policy_config_ = grpclb_config->child_policy(); } else { - child_policy_config_.reset(); + child_policy_config_ = nullptr; } } @@ -1802,6 +1806,24 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { policy_to_update->UpdateLocked(std::move(update_args)); } +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector(const char* desc, + InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + // // factory // @@ -1814,6 +1836,39 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kGrpclb; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + InlinedVector error_list; + UniquePtr child_policy = nullptr; + + for (const grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:childPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (parse_error != GRPC_ERROR_NONE) { + error_list.push_back(parse_error); + } + } + } + if (error_list.empty()) { + return UniquePtr( + New(std::move(child_policy), json)); + } else { + *error = CreateErrorFromVector("GrpcLb Parser", &error_list); + return nullptr; + } + } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 892472e1c9b..4b7b00237cb 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -531,6 +531,18 @@ void PickFirst::PickFirstSubchannelData:: } } +class ParsedPickFirstConfig : public ParsedLoadBalancingConfig { + public: + ParsedPickFirstConfig(const grpc_json* json) : json_(json) {} + + const char* name() const override { return kPickFirst; } + + const grpc_json* config() const { return json_; } + + private: + const grpc_json* json_; +}; + // // factory // @@ -543,6 +555,14 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kPickFirst; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + return UniquePtr( + New(json)); + } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 29cfe972f78..721844d689e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -509,6 +509,18 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } +class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig { + public: + ParsedRoundRobinConfig(const grpc_json* json) : json_(json) {} + + const char* name() const override { return kRoundRobin; } + + const grpc_json* config() const { return json_; } + + private: + const grpc_json* json_; +}; + // // factory // @@ -521,6 +533,14 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kRoundRobin; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + return UniquePtr( + New(json)); + } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 443deb01274..73b5de8f15a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -119,6 +119,38 @@ namespace { constexpr char kXds[] = "xds_experimental"; constexpr char kDefaultLocalityName[] = "xds_default_locality"; +class ParsedXdsConfig : public ParsedLoadBalancingConfig { + public: + ParsedXdsConfig(const char* balancer_name, + UniquePtr child_policy, + UniquePtr fallback_policy, + const grpc_json* json) + : balancer_name_(balancer_name), + child_policy_(std::move(child_policy)), + fallback_policy_(std::move(fallback_policy)), + json_(json) {} + + const char* name() const override { return kXds; } + + const char* balancer_name() const { return balancer_name_; }; + + const ParsedLoadBalancingConfig* child_policy() const { + return child_policy_.get(); + } + + const ParsedLoadBalancingConfig* fallback_policy() const { + return fallback_policy_.get(); + } + + const grpc_json* config() const { return json_; } + + private: + const char* balancer_name_ = nullptr; + UniquePtr child_policy_; + UniquePtr fallback_policy_; + const grpc_json* json_ = nullptr; +}; + class XdsLb : public LoadBalancingPolicy { public: explicit XdsLb(Args args); @@ -282,7 +314,7 @@ class XdsLb : public LoadBalancingPolicy { ~LocalityEntry() = default; void UpdateLocked(xds_grpclb_serverlist* serverlist, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); @@ -326,7 +358,7 @@ class XdsLb : public LoadBalancingPolicy { }; void UpdateLocked(const LocalityList& locality_list, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); @@ -364,7 +396,7 @@ class XdsLb : public LoadBalancingPolicy { // If parsing succeeds, updates \a balancer_name, and updates \a // child_policy_config_ and \a fallback_policy_config_ if they are also // found. Does nothing upon failure. - void ParseLbConfig(Config* xds_config); + void ParseLbConfig(const ParsedXdsConfig* xds_config); BalancerChannelState* LatestLbChannel() const { return pending_lb_chand_ != nullptr ? pending_lb_chand_.get() @@ -399,7 +431,7 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. - RefCountedPtr fallback_policy_config_; + const ParsedLoadBalancingConfig* fallback_policy_config_ = nullptr; int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. UniquePtr fallback_backend_addresses_; @@ -409,7 +441,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure lb_on_fallback_; // The policy to use for the backends. - RefCountedPtr child_policy_config_; + const ParsedLoadBalancingConfig* child_policy_config_ = nullptr; // Map of policies to use in the backend LocalityMap locality_map_; LocalityList locality_serverlist_; @@ -942,7 +974,7 @@ void XdsLb::BalancerChannelState::BalancerCallState:: xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; xdslb_policy->locality_map_.UpdateLocked( xdslb_policy->locality_serverlist_, - xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, + xdslb_policy->child_policy_config_, xdslb_policy->args_, xdslb_policy); } } else { @@ -1204,41 +1236,17 @@ void XdsLb::ProcessAddressesAndChannelArgsLocked( grpc_channel_args_destroy(lb_channel_args); } -void XdsLb::ParseLbConfig(Config* xds_config) { - const grpc_json* xds_config_json = xds_config->config(); - const char* balancer_name = nullptr; - grpc_json* child_policy = nullptr; - grpc_json* fallback_policy = nullptr; - for (const grpc_json* field = xds_config_json; field != nullptr; - field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "balancerName") == 0) { - if (balancer_name != nullptr) return; // Duplicate. - if (field->type != GRPC_JSON_STRING) return; - balancer_name = field->value; - } else if (strcmp(field->key, "childPolicy") == 0) { - if (child_policy != nullptr) return; // Duplicate. - child_policy = ParseLoadBalancingConfig(field); - } else if (strcmp(field->key, "fallbackPolicy") == 0) { - if (fallback_policy != nullptr) return; // Duplicate. - fallback_policy = ParseLoadBalancingConfig(field); - } - } - if (balancer_name == nullptr) return; // Required field. - balancer_name_ = UniquePtr(gpr_strdup(balancer_name)); - if (child_policy != nullptr) { - child_policy_config_ = - MakeRefCounted(child_policy, xds_config->service_config()); - } - if (fallback_policy != nullptr) { - fallback_policy_config_ = - MakeRefCounted(fallback_policy, xds_config->service_config()); - } +void XdsLb::ParseLbConfig(const ParsedXdsConfig* xds_config) { + if (xds_config == nullptr || xds_config->balancer_name() == nullptr) return; + // TODO(yashykt) : does this need to be a gpr_strdup + balancer_name_ = UniquePtr(gpr_strdup(xds_config->balancer_name())); + child_policy_config_ = xds_config->child_policy(); + fallback_policy_config_ = xds_config->fallback_policy(); } void XdsLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_chand_ == nullptr; - ParseLbConfig(args.config.get()); + ParseLbConfig(static_cast(args.config)); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. if (balancer_name_ == nullptr) { @@ -1251,8 +1259,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) { // have been created from a serverlist. // TODO(vpowar): Handle the fallback_address changes when we add support for // fallback in xDS. - locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(), - args_, this); + locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, args_, + this); // If this is the initial update, start the fallback timer. if (is_initial_update) { if (lb_fallback_timeout_ms_ > 0 && locality_serverlist_.empty() && @@ -1308,7 +1316,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1401,7 +1409,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - LoadBalancingPolicy::Config* child_policy_config, + const ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // This should never be invoked if we do not have serverlist_, as fallback @@ -1412,8 +1420,7 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( // Construct update args. UpdateArgs update_args; update_args.addresses = ProcessServerlist(serverlist); - update_args.config = - child_policy_config == nullptr ? nullptr : child_policy_config->Ref(); + update_args.config = child_policy_config; update_args.args = CreateChildPolicyArgsLocked(args_in); // If the child policy name changes, we need to create a new child @@ -1654,6 +1661,24 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { } } +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector(const char* desc, + InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + // // factory // @@ -1666,6 +1691,71 @@ class XdsFactory : public LoadBalancingPolicyFactory { } const char* name() const override { return kXds; } + + UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const override { + GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + + InlinedVector error_list; + const char* balancer_name = nullptr; + UniquePtr child_policy = nullptr; + UniquePtr fallback_policy = nullptr; + for (const grpc_json* field = json->child; field != nullptr; + field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "balancerName") == 0) { + if (balancer_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:Duplicate entry")); + continue; + } + if (field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:type should be string")); + continue; + } + balancer_name = field->value; + } else if (strcmp(field->key, "childPolicy") == 0) { + if (child_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:childPolicy error:Duplicate entry")); + continue; + } + grpc_error* parse_error = GRPC_ERROR_NONE; + child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (child_policy == nullptr) { + GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); + error_list.push_back(parse_error); + } + } else if (strcmp(field->key, "fallbackPolicy") == 0) { + if (fallback_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:fallbackPolicy error:Duplicate entry")); + } + grpc_error* parse_error = GRPC_ERROR_NONE; + fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (fallback_policy == nullptr) { + GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); + error_list.push_back(parse_error); + } + } + } + if (balancer_name == nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:balancerName error:not found")); + } + if (error_list.empty()) { + return UniquePtr( + New(balancer_name, std::move(child_policy), + std::move(fallback_policy), json)); + } else { + *error = CreateErrorFromVector("Xds Parser", &error_list); + return nullptr; + } + } }; } // namespace diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index 1da4b7c6956..cb7b547f589 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -27,6 +27,15 @@ namespace grpc_core { +class ParsedLoadBalancingConfig { + public: + virtual ~ParsedLoadBalancingConfig() = default; + + virtual const char* name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS; +}; + class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. @@ -37,9 +46,12 @@ class LoadBalancingPolicyFactory { /// Caller does NOT take ownership of result. virtual const char* name() const GRPC_ABSTRACT; + virtual UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error) const GRPC_ABSTRACT; + virtual ~LoadBalancingPolicyFactory() {} - GRPC_ABSTRACT_BASE_CLASS + GRPC_ABSTRACT_BASE_CLASS; }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index 99980d5500d..e22a0a793de 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -99,4 +99,28 @@ bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; } +UniquePtr +LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + GPR_ASSERT(g_state != nullptr); + const grpc_json* policy = + LoadBalancingPolicy::ParseLoadBalancingConfig(json, error); + if (policy == nullptr) { + return nullptr; + } else { + GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE); + // Find factory. + LoadBalancingPolicyFactory* factory = + g_state->GetLoadBalancingPolicyFactory(policy->key); + if (factory == nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig entry:Factory not found to create policy"); + return nullptr; + } + // Parse load balancing config via factory. + return factory->ParseLoadBalancingConfig(policy, error); + } +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 7472ba9f8a8..af85e511fbb 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -51,6 +51,9 @@ class LoadBalancingPolicyRegistry { /// Returns true if the LB policy factory specified by \a name exists in this /// registry. static bool LoadBalancingPolicyExists(const char* name); + + static UniquePtr ParseLoadBalancingConfig( + const grpc_json* json, grpc_error** error); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 7148e16e70b..69aeaf9eb85 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -35,6 +35,7 @@ #include "src/core/lib/channel/status_util.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/memory.h" +#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/uri/uri_parser.h" // As per the retry design, we do not allow more than 5 retry attempts. @@ -43,6 +44,9 @@ namespace grpc_core { namespace internal { +size_t ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index_; + ProcessedResolverResult::ProcessedResolverResult( Resolver::Result* resolver_result, bool parse_retry) : service_config_(resolver_result->service_config) { @@ -81,11 +85,38 @@ ProcessedResolverResult::ProcessedResolverResult( if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result); } +namespace { +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector(const char* desc, + InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} +} // namespace + void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, bool parse_retry) { if (service_config_ == nullptr) return; - service_config_json_ = - UniquePtr(gpr_strdup(service_config_->service_config_json())); + service_config_json_ = service_config_->service_config_json(); + auto* parsed_object = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index())); + + if (!parsed_object) { + return; + } if (parse_retry) { const grpc_arg* channel_arg = grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); @@ -94,29 +125,32 @@ void ProcessedResolverResult::ProcessServiceConfig( grpc_uri* uri = grpc_uri_parse(server_uri, true); GPR_ASSERT(uri->path[0] != '\0'); server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; - service_config_->ParseGlobalParams(ParseServiceConfig, this); + if (parsed_object->retry_throttling().has_value()) { + retry_throttle_data_ = + grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( + server_name_, + parsed_object->retry_throttling().value().max_milli_tokens, + parsed_object->retry_throttling().value().milli_token_ratio); + } grpc_uri_destroy(uri); + } + if (parsed_object->parsed_lb_config()) { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); + lb_policy_config_ = parsed_object->parsed_lb_config(); } else { - service_config_->ParseGlobalParams(ParseServiceConfig, this); + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); } - method_params_table_ = service_config_->CreateMethodConfigTable( - ClientChannelMethodParams::CreateFromJson); } void ProcessedResolverResult::ProcessLbPolicyName( const Resolver::Result& resolver_result) { - // Prefer the LB policy name found in the service config. Note that this is - // checking the deprecated loadBalancingPolicy field, rather than the new - // loadBalancingConfig field. - if (service_config_ != nullptr) { - lb_policy_name_.reset( - gpr_strdup(service_config_->GetLoadBalancingPolicyName())); - // Convert to lower-case. - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); - } + // Prefer the LB policy name found in the service config. + if (lb_policy_name_ != nullptr) { + char* lb_policy_name = lb_policy_name_.get(); + for (size_t i = 0; i < strlen(lb_policy_name); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); } } // Otherwise, find the LB policy name set by the client API. @@ -152,97 +186,8 @@ void ProcessedResolverResult::ProcessLbPolicyName( } } -void ProcessedResolverResult::ParseServiceConfig( - const grpc_json* field, ProcessedResolverResult* parsing_state) { - parsing_state->ParseLbConfigFromServiceConfig(field); - if (parsing_state->server_name_ != nullptr) { - parsing_state->ParseRetryThrottleParamsFromServiceConfig(field); - } -} - -void ProcessedResolverResult::ParseLbConfigFromServiceConfig( - const grpc_json* field) { - if (lb_policy_config_ != nullptr) return; // Already found. - if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0) { - return; // Not the LB config global parameter. - } - const grpc_json* policy = - LoadBalancingPolicy::ParseLoadBalancingConfig(field); - if (policy != nullptr) { - lb_policy_name_.reset(gpr_strdup(policy->key)); - lb_policy_config_ = - MakeRefCounted(policy, service_config_); - } -} - -void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig( - const grpc_json* field) { - if (strcmp(field->key, "retryThrottling") == 0) { - if (retry_throttle_data_ != nullptr) return; // Duplicate. - if (field->type != GRPC_JSON_OBJECT) return; - int max_milli_tokens = 0; - int milli_token_ratio = 0; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return; - if (strcmp(sub_field->key, "maxTokens") == 0) { - if (max_milli_tokens != 0) return; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return; - max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value); - if (max_milli_tokens == -1) return; - max_milli_tokens *= 1000; - } else if (strcmp(sub_field->key, "tokenRatio") == 0) { - if (milli_token_ratio != 0) return; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return; - // We support up to 3 decimal digits. - size_t whole_len = strlen(sub_field->value); - uint32_t multiplier = 1; - uint32_t decimal_value = 0; - const char* decimal_point = strchr(sub_field->value, '.'); - if (decimal_point != nullptr) { - whole_len = static_cast(decimal_point - sub_field->value); - multiplier = 1000; - size_t decimal_len = strlen(decimal_point + 1); - if (decimal_len > 3) decimal_len = 3; - if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, - &decimal_value)) { - return; - } - uint32_t decimal_multiplier = 1; - for (size_t i = 0; i < (3 - decimal_len); ++i) { - decimal_multiplier *= 10; - } - decimal_value *= decimal_multiplier; - } - uint32_t whole_value; - if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, - &whole_value)) { - return; - } - milli_token_ratio = - static_cast((whole_value * multiplier) + decimal_value); - if (milli_token_ratio <= 0) return; - } - } - retry_throttle_data_ = - grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( - server_name_, max_milli_tokens, milli_token_ratio); - } -} - namespace { -bool ParseWaitForReady( - grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) { - if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { - return false; - } - *wait_for_ready = field->type == GRPC_JSON_TRUE - ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE - : ClientChannelMethodParams::WAIT_FOR_READY_FALSE; - return true; -} - // Parses a JSON field of the form generated for a google.proto.Duration // proto message, as per: // https://developers.google.com/protocol-buffers/docs/proto3#json @@ -275,18 +220,37 @@ bool ParseDuration(grpc_json* field, grpc_millis* duration) { return true; } -UniquePtr ParseRetryPolicy( - grpc_json* field) { - auto retry_policy = MakeUnique(); - if (field->type != GRPC_JSON_OBJECT) return nullptr; +UniquePtr ParseRetryPolicy( + grpc_json* field, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + auto retry_policy = + MakeUnique(); + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:should be of type object"); + return nullptr; + } + InlinedVector error_list; for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { - if (sub_field->key == nullptr) return nullptr; + if (sub_field->key == nullptr) continue; if (strcmp(sub_field->key, "maxAttempts") == 0) { - if (retry_policy->max_attempts != 0) return nullptr; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return nullptr; + if (retry_policy->max_attempts != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:Duplicate entry")); + continue; + } // Duplicate. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:should be of type number")); + continue; + } retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value); - if (retry_policy->max_attempts <= 1) return nullptr; + if (retry_policy->max_attempts <= 1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxAttempts error:should be atleast 2")); + continue; + } if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) { gpr_log(GPR_ERROR, "service config: clamped retryPolicy.maxAttempts at %d", @@ -294,78 +258,314 @@ UniquePtr ParseRetryPolicy( retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS; } } else if (strcmp(sub_field->key, "initialBackoff") == 0) { - if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate. + if (retry_policy->initial_backoff > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:Duplicate entry")); + continue; + } if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:Failed to parse")); + continue; + } + if (retry_policy->initial_backoff == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:initialBackoff error:must be greater than 0")); } - if (retry_policy->initial_backoff == 0) return nullptr; } else if (strcmp(sub_field->key, "maxBackoff") == 0) { - if (retry_policy->max_backoff > 0) return nullptr; // Duplicate. + if (retry_policy->max_backoff > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:Duplicate entry")); + continue; + } if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:failed to parse")); + continue; + } + if (retry_policy->max_backoff == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxBackoff error:should be greater than 0")); } - if (retry_policy->max_backoff == 0) return nullptr; } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) { - if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate. - if (sub_field->type != GRPC_JSON_NUMBER) return nullptr; + if (retry_policy->backoff_multiplier != 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:Duplicate entry")); + continue; + } + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:should be of type number")); + continue; + } if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) != 1) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:failed to parse")); + continue; + } + if (retry_policy->backoff_multiplier <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:backoffMultiplier error:should be greater than 0")); } - if (retry_policy->backoff_multiplier <= 0) return nullptr; } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) { if (!retry_policy->retryable_status_codes.Empty()) { - return nullptr; // Duplicate. + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:Duplicate entry")); + continue; + } + if (sub_field->type != GRPC_JSON_ARRAY) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:should be of type array")); + continue; } - if (sub_field->type != GRPC_JSON_ARRAY) return nullptr; for (grpc_json* element = sub_field->child; element != nullptr; element = element->next) { - if (element->type != GRPC_JSON_STRING) return nullptr; + if (element->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:status codes should be of type " + "string")); + continue; + } grpc_status_code status; if (!grpc_status_code_from_string(element->value, &status)) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:failed to parse status code")); + continue; } retry_policy->retryable_status_codes.Add(status); } - if (retry_policy->retryable_status_codes.Empty()) return nullptr; + if (retry_policy->retryable_status_codes.Empty()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryableStatusCodes error:should be non-empty")); + }; } } // Make sure required fields are set. - if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 || - retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 || - retry_policy->retryable_status_codes.Empty()) { - return nullptr; + if (error_list.empty()) { + if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 || + retry_policy->max_backoff == 0 || + retry_policy->backoff_multiplier == 0 || + retry_policy->retryable_status_codes.Empty()) { + return nullptr; + } } - return retry_policy; + *error = CreateErrorFromVector("retryPolicy", &error_list); + return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; } } // namespace -RefCountedPtr -ClientChannelMethodParams::CreateFromJson(const grpc_json* json) { - RefCountedPtr method_params = - MakeRefCounted(); +UniquePtr +ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + InlinedVector error_list; + UniquePtr parsed_lb_config; + const char* lb_policy_name = nullptr; + grpc_core::Optional + retry_throttling; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) { + continue; // Not the LB config global parameter + } + // Parsed Load balancing config + if (strcmp(field->key, "loadBalancingConfig") == 0) { + if (parsed_lb_config != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingConfig error:Duplicate entry")); + } else { + grpc_error* parse_error = GRPC_ERROR_NONE; + parsed_lb_config = + LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, + &parse_error); + if (parsed_lb_config == nullptr) { + error_list.push_back(parse_error); + } + } + } + // Parse deprecated loadBalancingPolicy + if (strcmp(field->key, "loadBalancingPolicy") == 0) { + if (lb_policy_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:type should be string")); + } else if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + field->value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Unrecognized lb policy")); + } else { + lb_policy_name = field->value; + } + } + // Parse retry throttling + if (strcmp(field->key, "retryThrottling") == 0) { + if (field->type != GRPC_JSON_OBJECT) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Type should be object")); + } else if (retry_throttling.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Duplicate entry")); + } else { + grpc_core::Optional max_milli_tokens(false, 0); + grpc_core::Optional milli_token_ratio(false, 0); + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) continue; + if (strcmp(sub_field->key, "maxTokens") == 0) { + if (max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Duplicate " + "entry")); + } else if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Type should be " + "number")); + } else { + max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * + 1000); + if (max_milli_tokens.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:should be " + "greater than zero")); + } + } + } else if (strcmp(sub_field->key, "tokenRatio") == 0) { + if (milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Duplicate " + "entry")); + } else if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:type should be " + "number")); + } else { + // We support up to 3 decimal digits. + size_t whole_len = strlen(sub_field->value); + uint32_t multiplier = 1; + uint32_t decimal_value = 0; + const char* decimal_point = strchr(sub_field->value, '.'); + if (decimal_point != nullptr) { + whole_len = + static_cast(decimal_point - sub_field->value); + multiplier = 1000; + size_t decimal_len = strlen(decimal_point + 1); + if (decimal_len > 3) decimal_len = 3; + if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, + &decimal_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + uint32_t decimal_multiplier = 1; + for (size_t i = 0; i < (3 - decimal_len); ++i) { + decimal_multiplier *= 10; + } + decimal_value *= decimal_multiplier; + } + uint32_t whole_value; + if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, + &whole_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + milli_token_ratio.set( + static_cast((whole_value * multiplier) + decimal_value)); + if (milli_token_ratio.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:value should " + "be greater than 0")); + } + } + } + } + if (!max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Not found")); + } + if (!milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Not found")); + } + if (error_list.size() == 0) { + ClientChannelGlobalParsedObject::RetryThrottling data; + data.max_milli_tokens = max_milli_tokens.value(); + data.milli_token_ratio = milli_token_ratio.value(); + retry_throttling.set(data); + } + } + } + } + *error = CreateErrorFromVector("Client channel global parser", &error_list); + if (*error == GRPC_ERROR_NONE) { + return UniquePtr( + New(std::move(parsed_lb_config), + lb_policy_name, retry_throttling)); + } + return nullptr; +} + +UniquePtr +ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + InlinedVector error_list; + Optional wait_for_ready; + grpc_millis timeout = 0; + UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; if (strcmp(field->key, "waitForReady") == 0) { - if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) { - return nullptr; // Duplicate. + if (wait_for_ready.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:waitForReady error:Duplicate entry")); + continue; } - if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) { - return nullptr; + if (field->type == GRPC_JSON_TRUE) { + wait_for_ready.set(true); + } else if (field->type == GRPC_JSON_FALSE) { + wait_for_ready.set(false); + } else { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:waitForReady error:Type should be a true/false")); } } else if (strcmp(field->key, "timeout") == 0) { - if (method_params->timeout_ > 0) return nullptr; // Duplicate. - if (!ParseDuration(field, &method_params->timeout_)) return nullptr; + if (timeout > 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:timeout error:Duplicate entry")); + continue; + } + if (!ParseDuration(field, &timeout)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:timeout error:Failed parsing")); + }; } else if (strcmp(field->key, "retryPolicy") == 0) { - if (method_params->retry_policy_ != nullptr) { - return nullptr; // Duplicate. + if (retry_policy != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:Duplicate entry")); + continue; + } + grpc_error* error = GRPC_ERROR_NONE; + retry_policy = ParseRetryPolicy(field, &error); + if (retry_policy == nullptr) { + error_list.push_back(error); } - method_params->retry_policy_ = ParseRetryPolicy(field); - if (method_params->retry_policy_ == nullptr) return nullptr; } } - return method_params; + *error = CreateErrorFromVector("Client channel parser", &error_list); + if (*error == GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "hura"); + return UniquePtr( + New(timeout, wait_for_ready, + std::move(retry_policy))); + } + gpr_log(GPR_ERROR, "hura"); + return nullptr; } } // namespace internal diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index ad40c4991fe..41b5ccdcb65 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -22,10 +22,12 @@ #include #include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/status_util.h" +#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis @@ -35,11 +37,89 @@ namespace grpc_core { namespace internal { -class ClientChannelMethodParams; +class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { + public: + struct RetryThrottling { + int max_milli_tokens = 0; + int milli_token_ratio = 0; + }; + + ClientChannelGlobalParsedObject( + UniquePtr parsed_lb_config, + const char* parsed_deprecated_lb_policy, + const grpc_core::Optional& retry_throttling) + : parsed_lb_config_(std::move(parsed_lb_config)), + parsed_deprecated_lb_policy_(parsed_deprecated_lb_policy), + retry_throttling_(retry_throttling) {} + + grpc_core::Optional retry_throttling() const { + return retry_throttling_; + } + + const ParsedLoadBalancingConfig* parsed_lb_config() const { + return parsed_lb_config_.get(); + } + + const char* parsed_deprecated_lb_policy() const { + return parsed_deprecated_lb_policy_; + } + + private: + UniquePtr parsed_lb_config_; + const char* parsed_deprecated_lb_policy_ = nullptr; + grpc_core::Optional retry_throttling_; +}; + +class ClientChannelMethodParsedObject : public ServiceConfigParsedObject { + public: + struct RetryPolicy { + int max_attempts = 0; + grpc_millis initial_backoff = 0; + grpc_millis max_backoff = 0; + float backoff_multiplier = 0; + StatusCodeSet retryable_status_codes; + }; + + ClientChannelMethodParsedObject(grpc_millis timeout, + const Optional& wait_for_ready, + UniquePtr retry_policy) + : timeout_(timeout), + wait_for_ready_(wait_for_ready), + retry_policy_(std::move(retry_policy)) {} + + grpc_millis timeout() const { return timeout_; } + + Optional wait_for_ready() const { return wait_for_ready_; } + + const RetryPolicy* retry_policy() const { return retry_policy_.get(); } + + private: + grpc_millis timeout_ = 0; + Optional wait_for_ready_; + UniquePtr retry_policy_; +}; + +class ClientChannelServiceConfigParser : public ServiceConfigParser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override; -// A table mapping from a method name to its method parameters. -typedef SliceHashTable> - ClientChannelMethodParamsTable; + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static size_t client_channel_service_config_parser_index() { + return client_channel_service_config_parser_index_; + } + + static void Register() { + client_channel_service_config_parser_index_ = + ServiceConfig::RegisterParser(UniquePtr( + New())); + } + + private: + static size_t client_channel_service_config_parser_index_; +}; // A container of processed fields from the resolver result. Simplifies the // usage of resolver result. @@ -51,18 +131,14 @@ class ProcessedResolverResult { ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry); // Getters. Any managed object's ownership is transferred. - UniquePtr service_config_json() { - return std::move(service_config_json_); - } + const char* service_config_json() { return service_config_json_; } RefCountedPtr retry_throttle_data() { return std::move(retry_throttle_data_); } - RefCountedPtr method_params_table() { - return std::move(method_params_table_); - } + UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } - RefCountedPtr lb_policy_config() { - return std::move(lb_policy_config_); + const ParsedLoadBalancingConfig* lb_policy_config() { + return lb_policy_config_; } RefCountedPtr service_config() { return service_config_; } @@ -85,59 +161,14 @@ class ProcessedResolverResult { void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field); // Service config. - UniquePtr service_config_json_; + const char* service_config_json_ = nullptr; RefCountedPtr service_config_; // LB policy. UniquePtr lb_policy_name_; - RefCountedPtr lb_policy_config_; + const ParsedLoadBalancingConfig* lb_policy_config_ = nullptr; // Retry throttle data. char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; - // Method params table. - RefCountedPtr method_params_table_; -}; - -// The parameters of a method. -class ClientChannelMethodParams : public RefCounted { - public: - enum WaitForReady { - WAIT_FOR_READY_UNSET = 0, - WAIT_FOR_READY_FALSE, - WAIT_FOR_READY_TRUE - }; - - struct RetryPolicy { - int max_attempts = 0; - grpc_millis initial_backoff = 0; - grpc_millis max_backoff = 0; - float backoff_multiplier = 0; - StatusCodeSet retryable_status_codes; - }; - - /// Creates a method_parameters object from \a json. - /// Intended for use with ServiceConfig::CreateMethodConfigTable(). - static RefCountedPtr CreateFromJson( - const grpc_json* json); - - grpc_millis timeout() const { return timeout_; } - WaitForReady wait_for_ready() const { return wait_for_ready_; } - const RetryPolicy* retry_policy() const { return retry_policy_.get(); } - - private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - // So Delete() can call our private dtor. - template - friend void grpc_core::Delete(T*); - - ClientChannelMethodParams() {} - virtual ~ClientChannelMethodParams() {} - - grpc_millis timeout_ = 0; - WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET; - UniquePtr retry_policy_; }; } // namespace internal diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index a2367e09d9b..2d0f72f8520 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -192,8 +192,8 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, - UniquePtr child_policy_name, RefCountedPtr child_lb_config, - grpc_error** error) + UniquePtr child_policy_name, + const ParsedLoadBalancingConfig* child_lb_config, grpc_error** error) : LoadBalancingPolicy(std::move(args)), tracer_(tracer), target_uri_(std::move(target_uri)), @@ -341,8 +341,9 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { } void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( - const char* lb_policy_name, RefCountedPtr lb_policy_config, - Resolver::Result result, TraceStringVector* trace_strings) { + const char* lb_policy_name, + const ParsedLoadBalancingConfig* lb_policy_config, Resolver::Result result, + TraceStringVector* trace_strings) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -538,7 +539,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const bool resolution_contains_addresses = result.addresses.size() > 0; // Process the resolver result. const char* lb_policy_name = nullptr; - RefCountedPtr lb_policy_config; + const ParsedLoadBalancingConfig* lb_policy_config = nullptr; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { service_config_changed = @@ -550,7 +551,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( } GPR_ASSERT(lb_policy_name != nullptr); // Create or update LB policy, as needed. - CreateOrUpdateLbPolicyLocked(lb_policy_name, std::move(lb_policy_config), + CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, std::move(result), &trace_strings); // Add channel trace event. if (channelz_node() != nullptr) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index c9349769dd2..d36ae627066 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -23,6 +23,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/lb_policy.h" +#include "src/core/ext/filters/client_channel/lb_policy_factory.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -56,7 +57,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, UniquePtr target_uri, UniquePtr child_policy_name, - RefCountedPtr child_lb_config, + const ParsedLoadBalancingConfig* child_lb_config, grpc_error** error); // Private ctor, to be used by client_channel only! @@ -66,7 +67,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Returns true if the service config has changed since the last result. typedef bool (*ProcessResolverResultCallback)( void* user_data, Resolver::Result* result, const char** lb_policy_name, - RefCountedPtr* lb_policy_config); + const ParsedLoadBalancingConfig** lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -102,10 +103,10 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void StartResolvingLocked(); void OnResolverError(grpc_error* error); - void CreateOrUpdateLbPolicyLocked(const char* lb_policy_name, - RefCountedPtr lb_policy_config, - Resolver::Result result, - TraceStringVector* trace_strings); + void CreateOrUpdateLbPolicyLocked( + const char* lb_policy_name, + const ParsedLoadBalancingConfig* lb_policy_config, + Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); @@ -121,7 +122,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - RefCountedPtr child_lb_config_; + const ParsedLoadBalancingConfig* child_lb_config_ = nullptr; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index d9e64ccf5a8..06a413a89af 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -134,8 +134,11 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( } objs_vector->push_back(std::move(parsed_obj)); } - const auto* vector_ptr = objs_vector.get(); service_config_objects_vectors_storage_.push_back(std::move(objs_vector)); + const auto* vector_ptr = + service_config_objects_vectors_storage_ + [service_config_objects_vectors_storage_.size() - 1] + .get(); // Construct list of paths. InlinedVector, 10> paths; for (grpc_json* child = json->child; child != nullptr; child = child->next) { @@ -231,23 +234,6 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } -const char* ServiceConfig::GetLoadBalancingPolicyName() const { - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return nullptr; - } - const char* lb_policy_name = nullptr; - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "loadBalancingPolicy") == 0) { - if (lb_policy_name != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_STRING) return nullptr; - lb_policy_name = field->value; - } - } - return lb_policy_name; -} - int ServiceConfig::CountNamesInMethodConfig(grpc_json* json) { int num_names = 0; for (grpc_json* field = json->child; field != nullptr; field = field->next) { @@ -319,8 +305,11 @@ UniquePtr ServiceConfig::ParseJsonMethodName(grpc_json* json, return UniquePtr(path); } -const ServiceConfig::ServiceConfigObjectsVector* const* +const ServiceConfig::ServiceConfigObjectsVector* ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { + if (parsed_method_service_config_objects_table_.get() == nullptr) { + return nullptr; + } const auto* value = parsed_method_service_config_objects_table_->Get(path); // If we didn't find a match for the path, try looking for a wildcard // entry (i.e., change "/service/method" to "/service/*"). @@ -339,7 +328,7 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { gpr_free(path_str); if (value == nullptr) return nullptr; } - return value; + return *value; } size_t ServiceConfig::RegisterParser(UniquePtr parser) { diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 0f2d2b387ae..5ec6c6de346 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -107,11 +107,6 @@ class ServiceConfig : public RefCounted { template void ParseGlobalParams(ProcessJson process_json, T* arg) const; - /// Gets the LB policy name from \a service_config. - /// Returns NULL if no LB policy name was specified. - /// Caller does NOT take ownership. - const char* GetLoadBalancingPolicyName() const; - /// Creates a method config table based on the data in \a json. /// The table's keys are request paths. The table's value type is /// returned by \a create_value(), based on data parsed from the JSON tree. @@ -141,7 +136,7 @@ class ServiceConfig : public RefCounted { /// Retrieves the vector of method service config objects for a given path \a /// path. - const ServiceConfigObjectsVector* const* GetMethodServiceConfigObjectsVector( + const ServiceConfigObjectsVector* GetMethodServiceConfigObjectsVector( const grpc_slice& path); /// Globally register a service config parser. On successful registration, it diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 722c22c4623..3c91f9365f8 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -37,6 +37,8 @@ typedef enum { GRPC_SERVICE_CONFIG, + GRPC_SERVICE_CONFIG_METHOD_PARAMS, + GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index a8e3ce1505e..5c519fe7ec0 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,6 +26,9 @@ namespace grpc_core { template class Optional { public: + Optional() = default; + + Optional(bool set, T value) : set_(set), value_(value) {} void set(const T& val) { value_ = val; set_ = true; @@ -38,8 +41,8 @@ class Optional { T value() const { return value_; } private: - T value_; bool set_ = false; + T value_; }; } /* namespace grpc_core */ diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index fcc6f0761b3..99a148ddc26 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,6 +30,7 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 10cb4cd4404..229944435b0 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -21,6 +21,7 @@ #include #include +#include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" @@ -201,6 +202,9 @@ TEST_F(ServiceConfigTest, Parser1BasicTest1) { EXPECT_TRUE((static_cast( svc_cfg->GetParsedGlobalServiceConfigObject(0))) ->value() == 5); + EXPECT_TRUE(svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")) == + nullptr); } TEST_F(ServiceConfigTest, Parser1BasicTest2) { @@ -252,11 +256,10 @@ TEST_F(ServiceConfigTest, Parser2BasicTest) { grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); ASSERT_TRUE(error == GRPC_ERROR_NONE); - const auto* const* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( grpc_slice_from_static_string("/TestServ/TestMethod")); EXPECT_TRUE(vector_ptr != nullptr); - const auto* vector = *vector_ptr; - auto parsed_object = ((*vector)[1]).get(); + auto parsed_object = ((*vector_ptr)[1]).get(); EXPECT_TRUE(static_cast(parsed_object)->value() == 5); } @@ -352,6 +355,58 @@ TEST_F(ErroredParsersScopingTest, MethodParams) { GRPC_ERROR_UNREF(error); } +class ClientChannelParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE( + ServiceConfig::RegisterParser(UniquePtr( + New())) == + 0); + } +}; + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig1) { + const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig2) { + const char* test_json = + "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig3) { + const char* test_json = + "{\"loadBalancingConfig\": " + "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); +} + } // namespace testing } // namespace grpc_core From 2c4c8438cc11e4ffbac2ed10078a0513d5036b37 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 18 Apr 2019 11:27:54 -0700 Subject: [PATCH 025/112] Message size filter parser and health check parser --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 6 + Makefile | 6 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../client_channel/client_channel_plugin.cc | 2 + .../health/health_check_parser.cc | 75 ++++++++ .../health/health_check_parser.h | 49 +++++ .../filters/client_channel/service_config.h | 5 +- .../message_size/message_size_filter.cc | 179 +++++++++++++----- .../message_size/message_size_filter.h | 13 ++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 3 + 21 files changed, 312 insertions(+), 49 deletions(-) create mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.cc create mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.h diff --git a/BUILD b/BUILD index ec9f58dbed1..104351bd1ad 100644 --- a/BUILD +++ b/BUILD @@ -1081,6 +1081,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/global_subchannel_pool.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc", + "src/core/ext/filters/client_channel/health/health_check_parser.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", @@ -1107,6 +1108,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/connector.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", diff --git a/BUILD.gn b/BUILD.gn index 78e434477b8..feb0225a037 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -260,6 +260,8 @@ config("grpc_config") { "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/health/health_check_parser.cc", + "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d5e448d688..f268f4156fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1232,6 +1232,7 @@ add_library(grpc src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1586,6 +1587,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1965,6 +1967,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2289,6 +2292,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2624,6 +2628,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -3496,6 +3501,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc + src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc diff --git a/Makefile b/Makefile index c3c7412590d..ed5d1329679 100644 --- a/Makefile +++ b/Makefile @@ -3687,6 +3687,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4035,6 +4036,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4407,6 +4409,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4718,6 +4721,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -5027,6 +5031,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -5875,6 +5880,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ diff --git a/build.yaml b/build.yaml index 8752447f125..c8b4619bae7 100644 --- a/build.yaml +++ b/build.yaml @@ -574,6 +574,7 @@ filegroups: - src/core/ext/filters/client_channel/connector.h - src/core/ext/filters/client_channel/global_subchannel_pool.h - src/core/ext/filters/client_channel/health/health_check_client.h + - src/core/ext/filters/client_channel/health/health_check_parser.h - src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/lb_policy.h @@ -603,6 +604,7 @@ filegroups: - src/core/ext/filters/client_channel/connector.cc - src/core/ext/filters/client_channel/global_subchannel_pool.cc - src/core/ext/filters/client_channel/health/health_check_client.cc + - src/core/ext/filters/client_channel/health/health_check_parser.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc diff --git a/config.m4 b/config.m4 index 2c64a3eb168..03576f2f90c 100644 --- a/config.m4 +++ b/config.m4 @@ -347,6 +347,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ + src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ diff --git a/config.w32 b/config.w32 index 6897c1041ac..b727e989717 100644 --- a/config.w32 +++ b/config.w32 @@ -322,6 +322,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\connector.cc " + "src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + + "src\\core\\ext\\filters\\client_channel\\health\\health_check_parser.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 7c90454f1a9..1ce79bed4ca 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -368,6 +368,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', + 'src/core/ext/filters/client_channel/health/health_check_parser.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index c58152cf7f8..e5849c21066 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -347,6 +347,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', + 'src/core/ext/filters/client_channel/health/health_check_parser.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -794,6 +795,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', + 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -987,6 +989,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', + 'src/core/ext/filters/client_channel/health/health_check_parser.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', diff --git a/grpc.gemspec b/grpc.gemspec index c41db6f6293..2230b2d1d4d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -281,6 +281,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/connector.h ) s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) + s.files += %w( src/core/ext/filters/client_channel/health/health_check_parser.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) @@ -731,6 +732,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/connector.cc ) s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) + s.files += %w( src/core/ext/filters/client_channel/health/health_check_parser.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) diff --git a/grpc.gyp b/grpc.gyp index 322259d2ca7..66cfa592832 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -529,6 +529,7 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', + 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -792,6 +793,7 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', + 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1036,6 +1038,7 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', + 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1291,6 +1294,7 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', + 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', diff --git a/package.xml b/package.xml index 5be3d24365d..27d6da303b3 100644 --- a/package.xml +++ b/package.xml @@ -286,6 +286,7 @@ + @@ -736,6 +737,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 12f02fc49fb..b699f995b37 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -34,6 +34,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" +#include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { @@ -51,6 +52,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { void grpc_service_config_register_parsers() { grpc_core::internal::ClientChannelServiceConfigParser::Register(); + grpc_core::MessageSizeParser::Register(); } void grpc_client_channel_init(void) { diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc new file mode 100644 index 00000000000..b9ccc3cb3b6 --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -0,0 +1,75 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" + +namespace grpc_core { +namespace { +size_t health_check_parser_index; +} + +UniquePtr HealthCheckParser::ParseGlobalParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + const char* service_name = nullptr; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) { + continue; + } + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type object"); + return nullptr; + } + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) { + continue; + } + if (strcmp(sub_field->key, "serviceName") == 0) { + if (service_name != nullptr) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig field:serviceName error:Duplicate " + "entry"); + return nullptr; + } + if (sub_field->type != GRPC_JSON_STRING) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type string"); + return nullptr; + } + service_name = sub_field->value; + } + } + } + } + return UniquePtr( + New(service_name)); +} + +void HealthCheckParser::Register() { + health_check_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t HealthCheckParser::ParserIndex() { return health_check_parser_index; } + +} // namespace grpc_core \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h new file mode 100644 index 00000000000..8ab1ba9425d --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_parser.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H + +#include + +#include "src/core/ext/filters/client_channel/service_config.h" + +namespace grpc_core { + +class HealthCheckParsedObject : public ServiceConfigParsedObject { + public: + HealthCheckParsedObject(const char* service_name) + : service_name_(service_name) {} + + const char* service_name() const { return service_name_; } + + private: + const char* service_name_; +}; + +class HealthCheckParser : public ServiceConfigParser { + public: + UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; +} // namespace grpc_core +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 5ec6c6de346..28e482bf2b7 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -128,9 +128,8 @@ class ServiceConfig : public RefCounted { const SliceHashTable>& table, const grpc_slice& path); /// Retrieves the parsed global service config object at index \a index. - ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(int index) { - GPR_DEBUG_ASSERT( - index < static_cast(parsed_global_service_config_objects_.size())); + ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(size_t index) { + GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); return parsed_global_service_config_objects_[index].get(); } diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 4d120c0eb76..26c78241b70 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -32,6 +32,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel_init.h" typedef struct { @@ -39,55 +40,118 @@ typedef struct { int max_recv_size; } message_size_limits; -namespace grpc_core { namespace { +size_t message_size_parser_index; -class MessageSizeLimits : public RefCounted { - public: - static RefCountedPtr CreateFromJson(const grpc_json* json); - - const message_size_limits& limits() const { return limits_; } +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector( + const char* desc, grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} +} // namespace - private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); +namespace grpc_core { - MessageSizeLimits(int max_send_size, int max_recv_size) { +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + MessageSizeParsedObject(int max_send_size, int max_recv_size) { limits_.max_send_size = max_send_size; limits_.max_recv_size = max_recv_size; } + const message_size_limits& limits() const { return limits_; } + + private: message_size_limits limits_; }; -RefCountedPtr MessageSizeLimits::CreateFromJson( - const grpc_json* json) { +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); int max_request_message_bytes = -1; int max_response_message_bytes = -1; + InlinedVector error_list; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) return nullptr; // Duplicate. + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + continue; + } if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + continue; } max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) return nullptr; + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) return nullptr; // Duplicate. + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + continue; + } if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); } max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) return nullptr; + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } } } - return MakeRefCounted(max_request_message_bytes, - max_response_message_bytes); + if (!error_list.empty()) { + *error = CreateErrorFromVector("Message size parser", &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); } -} // namespace +void MessageSizeParser::Register() { + gpr_log(GPR_ERROR, "registered"); + message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return message_size_parser_index; } + +class MessageSizeLimits : public RefCounted { + public: + static RefCountedPtr CreateFromJson(const grpc_json* json); + + const message_size_limits& limits() const { return limits_; } + + private: + // So New() can call our private ctor. + template + friend T* grpc_core::New(Args&&... args); + + MessageSizeLimits(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + message_size_limits limits_; +}; } // namespace grpc_core static void recv_message_ready(void* user_data, grpc_error* error); @@ -97,6 +161,7 @@ namespace { struct channel_data { message_size_limits limits; + grpc_core::RefCountedPtr svc_cfg; // Maps path names to refcounted_message_size_limits structs. grpc_core::RefCountedPtr>> @@ -116,21 +181,32 @@ struct call_data { // Note: Per-method config is only available on the client, so we // apply the max request size to the send limit and the max response // size to the receive limit. - if (chand.method_limit_table != nullptr) { - grpc_core::RefCountedPtr limits = - grpc_core::ServiceConfig::MethodConfigTableLookup( - *chand.method_limit_table, args.path); - if (limits != nullptr) { - if (limits->limits().max_send_size >= 0 && - (limits->limits().max_send_size < this->limits.max_send_size || - this->limits.max_send_size < 0)) { - this->limits.max_send_size = limits->limits().max_send_size; - } - if (limits->limits().max_recv_size >= 0 && - (limits->limits().max_recv_size < this->limits.max_recv_size || - this->limits.max_recv_size < 0)) { - this->limits.max_recv_size = limits->limits().max_recv_size; - } + const grpc_core::MessageSizeParsedObject* limits = nullptr; + const grpc_core::ServiceConfig::ServiceConfigObjectsVector* objs_vector = + static_cast< + const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( + args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + if (objs_vector != nullptr) { + limits = static_cast( + (*objs_vector)[message_size_parser_index].get()); + } else if (chand.svc_cfg != nullptr) { + objs_vector = + chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); + if (objs_vector != nullptr) { + limits = static_cast( + (*objs_vector)[message_size_parser_index].get()); + } + } + if (limits != nullptr) { + if (limits->limits().max_send_size >= 0 && + (limits->limits().max_send_size < this->limits.max_send_size || + this->limits.max_send_size < 0)) { + this->limits.max_send_size = limits->limits().max_send_size; + } + if (limits->limits().max_recv_size >= 0 && + (limits->limits().max_recv_size < this->limits.max_recv_size || + this->limits.max_recv_size < 0)) { + this->limits.max_recv_size = limits->limits().max_recv_size; } } } @@ -313,6 +389,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { GPR_ASSERT(!args->is_last); channel_data* chand = static_cast(elem->channel_data); + new (chand) channel_data(); chand->limits = get_message_size_limits(args->channel_args); // Get method config table from channel args. const grpc_arg* channel_arg = @@ -320,14 +397,14 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, const char* service_config_str = grpc_channel_arg_get_string(channel_arg); if (service_config_str != nullptr) { grpc_error* service_config_error = GRPC_ERROR_NONE; - grpc_core::RefCountedPtr service_config = - grpc_core::ServiceConfig::Create(service_config_str, - &service_config_error); - GRPC_ERROR_UNREF(service_config_error); - if (service_config != nullptr) { - chand->method_limit_table = service_config->CreateMethodConfigTable( - grpc_core::MessageSizeLimits::CreateFromJson); + auto svc_cfg = grpc_core::ServiceConfig::Create(service_config_str, + &service_config_error); + if (service_config_error == GRPC_ERROR_NONE) { + chand->svc_cfg = std::move(svc_cfg); + } else { + gpr_log(GPR_ERROR, "%s", grpc_error_string(service_config_error)); } + GRPC_ERROR_UNREF(service_config_error); } return GRPC_ERROR_NONE; } @@ -351,6 +428,15 @@ const grpc_channel_filter grpc_message_size_filter = { grpc_channel_next_get_info, "message_size"}; +// Used for GRPC_CLIENT_SUBCHANNEL +static bool add_message_size_filter(grpc_channel_stack_builder* builder, + void* arg) { + return grpc_channel_stack_builder_prepend_filter( + builder, &grpc_message_size_filter, nullptr, nullptr); +} + +// Used for GRPC_CLIENT_DIRECT_CHANNEL and GRPC_SERVER_CHANNEL. Adds the filter +// only if message size limits or service config is specified. static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, void* arg) { const grpc_channel_args* channel_args = @@ -362,7 +448,8 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, } const grpc_arg* a = grpc_channel_args_find(channel_args, GRPC_ARG_SERVICE_CONFIG); - if (a != nullptr) { + const char* svc_cfg_str = grpc_channel_arg_get_string(a); + if (svc_cfg_str != nullptr) { enable = true; } if (enable) { @@ -376,7 +463,7 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, void grpc_message_size_filter_init(void) { grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, - maybe_add_message_size_filter, nullptr); + add_message_size_filter, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index f66636e5832..6f0f16ab67c 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -19,8 +19,21 @@ #include +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_stack.h" extern const grpc_channel_filter grpc_message_size_filter; +namespace grpc_core { +class MessageSizeParser : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; +} // namespace grpc_core + #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 21efd682871..59a19be99ea 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -321,6 +321,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', + 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1817be44bc3..2fbf8abb54f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -892,6 +892,8 @@ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.h \ +src/core/ext/filters/client_channel/health/health_check_parser.cc \ +src/core/ext/filters/client_channel/health/health_check_parser.h \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.h \ src/core/ext/filters/client_channel/http_proxy.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 1782e18eb1d..c2f869d7cbb 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8694,6 +8694,7 @@ "src/core/ext/filters/client_channel/connector.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", @@ -8734,6 +8735,8 @@ "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", + "src/core/ext/filters/client_channel/health/health_check_parser.cc", + "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.cc", From 116ce0fb24ffa5ae471b3dc8bbc942fa24d904a1 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 18 Apr 2019 14:43:48 -0700 Subject: [PATCH 026/112] Use health check parser --- .../filters/client_channel/client_channel.cc | 12 +++-- .../client_channel/client_channel_factory.h | 6 ++- .../client_channel/client_channel_plugin.cc | 2 + .../ext/filters/client_channel/lb_policy.cc | 6 +++ .../ext/filters/client_channel/lb_policy.h | 6 ++- .../client_channel/lb_policy/grpclb/grpclb.cc | 11 +++-- .../lb_policy/pick_first/pick_first.cc | 8 ++-- .../lb_policy/round_robin/round_robin.cc | 8 ++-- .../lb_policy/subchannel_list.h | 7 +-- .../client_channel/lb_policy/xds/xds.cc | 10 +++-- .../client_channel/resolver_result_parsing.cc | 5 ++- .../client_channel/resolver_result_parsing.h | 3 ++ .../client_channel/resolving_lb_policy.cc | 20 ++++++--- .../client_channel/resolving_lb_policy.h | 6 ++- .../ext/filters/client_channel/subchannel.cc | 45 ++++--------------- .../ext/filters/client_channel/subchannel.h | 7 ++- .../message_size/message_size_filter.cc | 1 - .../chttp2/client/insecure/channel_create.cc | 6 ++- .../client/secure/secure_channel_create.cc | 6 ++- test/core/util/test_lb_policies.cc | 7 ++- test/cpp/microbenchmarks/bm_call_create.cc | 4 +- 21 files changed, 106 insertions(+), 80 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 262795b025c..f0847000b10 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -438,13 +438,15 @@ class ClientChannelControlHelper "ClientChannelControlHelper"); } - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override { grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool.get()); grpc_channel_args* new_args = grpc_channel_args_copy_and_add(&args, &arg, 1); - Subchannel* subchannel = - chand_->client_channel_factory->CreateSubchannel(new_args); + Subchannel* subchannel = chand_->client_channel_factory->CreateSubchannel( + new_args, health_check); grpc_channel_args_destroy(new_args); return subchannel; } @@ -491,7 +493,8 @@ class ClientChannelControlHelper // result update. static bool process_resolver_result_locked( void* arg, grpc_core::Resolver::Result* result, const char** lb_policy_name, - const grpc_core::ParsedLoadBalancingConfig** lb_policy_config) { + const grpc_core::ParsedLoadBalancingConfig** lb_policy_config, + const grpc_core::HealthCheckParsedObject** health_check) { channel_data* chand = static_cast(arg); ProcessedResolverResult resolver_result(result, chand->enable_retries); const char* service_config_json = resolver_result.service_config_json(); @@ -517,6 +520,7 @@ static bool process_resolver_result_locked( // Return results. *lb_policy_name = chand->info_lb_policy_name.get(); *lb_policy_config = resolver_result.lb_policy_config(); + *health_check = resolver_result.health_check(); return service_config_changed; } diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 21f78a833df..43a696da983 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -23,6 +23,7 @@ #include +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/gprpp/abstract.h" @@ -33,8 +34,9 @@ class ClientChannelFactory { virtual ~ClientChannelFactory() = default; // Creates a subchannel with the specified args. - virtual Subchannel* CreateSubchannel(const grpc_channel_args* args) - GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel( + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; // Creates a channel for the specified target with the specified args. virtual grpc_channel* CreateChannel( diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index b699f995b37..92b1fed61d1 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -27,6 +27,7 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/global_subchannel_pool.h" +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/http_proxy.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" @@ -53,6 +54,7 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { void grpc_service_config_register_parsers() { grpc_core::internal::ClientChannelServiceConfigParser::Register(); grpc_core::MessageSizeParser::Register(); + grpc_core::HealthCheckParser::Register(); } void grpc_client_channel_init(void) { diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 1cd5e6c9e98..cd6397a4ae2 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -117,12 +117,15 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) { addresses = other.addresses; config = other.config; + health_check = other.health_check; args = grpc_channel_args_copy(other.args); } LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); + health_check = other.health_check; + other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. args = other.args; other.args = nullptr; @@ -132,6 +135,7 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( const UpdateArgs& other) { addresses = other.addresses; config = other.config; + health_check = other.health_check; grpc_channel_args_destroy(args); args = grpc_channel_args_copy(other.args); return *this; @@ -141,6 +145,8 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); + health_check = other.health_check; + other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. grpc_channel_args_destroy(args); args = other.args; diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 30e6dca1cd9..a8857e9b6a7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -175,8 +175,9 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual ~ChannelControlHelper() = default; /// Creates a new subchannel with the specified channel args. - virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) - GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; /// Creates a channel with the specified target and channel args. /// This can be used in cases where the LB policy needs to create a @@ -201,6 +202,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { struct UpdateArgs { ServerAddressList addresses; const ParsedLoadBalancingConfig* config = nullptr; + const HealthCheckParsedObject* health_check = nullptr; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index f8922bf7bcc..8e2dbfa8d5d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -295,7 +295,9 @@ class GrpcLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, grpc_error* state_error, @@ -620,12 +622,15 @@ bool GrpcLb::Helper::CalledByCurrentChild() const { return child_ == parent_->child_policy_.get(); } -Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { +Subchannel* GrpcLb::Helper::CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) { if (parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return parent_->channel_control_helper()->CreateSubchannel(args); + return parent_->channel_control_helper()->CreateSubchannel(args, + health_check); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 4b7b00237cb..ff58cee645e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -88,9 +88,10 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args) + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args) { + policy->channel_control_helper(), args, health_check) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -254,7 +255,8 @@ void PickFirst::UpdateLocked(UpdateArgs args) { grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); + this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args, + args.health_check); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 721844d689e..7284410ce09 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -109,9 +109,10 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args) + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args) { + policy->channel_control_helper(), args, health_check) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -488,7 +489,8 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); + this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args, + args.health_check); if (latest_pending_subchannel_list_->num_subchannels() == 0) { // If the new list is empty, immediately promote the new list to the // current list and transition to TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 4fde90c2584..58aebb22909 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -233,7 +233,8 @@ class SubchannelList : public InternallyRefCounted { SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args); + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check); virtual ~SubchannelList(); @@ -487,7 +488,7 @@ SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args) + const grpc_channel_args& args, const HealthCheckParsedObject* health_check) : InternallyRefCounted(tracer), policy_(policy), tracer_(tracer), @@ -522,7 +523,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = helper->CreateSubchannel(*new_args); + Subchannel* subchannel = helper->CreateSubchannel(*new_args, health_check); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 73b5de8f15a..804417c177e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -328,7 +328,9 @@ class XdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr entry) : entry_(std::move(entry)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override; + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, grpc_error* state_error, @@ -1576,12 +1578,14 @@ bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const { } Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( - const grpc_channel_args& args) { + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) { if (entry_->parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return entry_->parent_->channel_control_helper()->CreateSubchannel(args); + return entry_->parent_->channel_control_helper()->CreateSubchannel( + args, health_check); } grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel( diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 69aeaf9eb85..60b6288296a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -108,6 +108,9 @@ grpc_error* CreateErrorFromVector(const char* desc, void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, bool parse_retry) { if (service_config_ == nullptr) return; + health_check_ = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + HealthCheckParser::ParserIndex())); service_config_json_ = service_config_->service_config_json(); auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( @@ -559,12 +562,10 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, } *error = CreateErrorFromVector("Client channel parser", &error_list); if (*error == GRPC_ERROR_NONE) { - gpr_log(GPR_ERROR, "hura"); return UniquePtr( New(timeout, wait_for_ready, std::move(retry_policy))); } - gpr_log(GPR_ERROR, "hura"); return nullptr; } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 41b5ccdcb65..6e73c43a779 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -140,6 +140,8 @@ class ProcessedResolverResult { const ParsedLoadBalancingConfig* lb_policy_config() { return lb_policy_config_; } + + const HealthCheckParsedObject* health_check() { return health_check_; } RefCountedPtr service_config() { return service_config_; } private: @@ -169,6 +171,7 @@ class ProcessedResolverResult { // Retry throttle data. char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; + const HealthCheckParsedObject* health_check_ = nullptr; }; } // namespace internal diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 2d0f72f8520..3eaae1cd39a 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -106,10 +106,13 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; - return parent_->channel_control_helper()->CreateSubchannel(args); + return parent_->channel_control_helper()->CreateSubchannel(args, + health_check); } grpc_channel* CreateChannel(const char* target, @@ -343,7 +346,8 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, Resolver::Result result, - TraceStringVector* trace_strings) { + TraceStringVector* trace_strings, + const HealthCheckParsedObject* health_check) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -436,6 +440,7 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( UpdateArgs update_args; update_args.addresses = std::move(result.addresses); update_args.config = std::move(lb_policy_config); + update_args.health_check = health_check; // TODO(roth): Once channel args is converted to C++, use std::move() here. update_args.args = result.args; result.args = nullptr; @@ -540,11 +545,12 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // Process the resolver result. const char* lb_policy_name = nullptr; const ParsedLoadBalancingConfig* lb_policy_config = nullptr; + const HealthCheckParsedObject* health_check = nullptr; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { - service_config_changed = - process_resolver_result_(process_resolver_result_user_data_, &result, - &lb_policy_name, &lb_policy_config); + service_config_changed = process_resolver_result_( + process_resolver_result_user_data_, &result, &lb_policy_name, + &lb_policy_config, &health_check); } else { lb_policy_name = child_policy_name_.get(); lb_policy_config = child_lb_config_; @@ -552,7 +558,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( GPR_ASSERT(lb_policy_name != nullptr); // Create or update LB policy, as needed. CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, - std::move(result), &trace_strings); + std::move(result), &trace_strings, health_check); // Add channel trace event. if (channelz_node() != nullptr) { if (service_config_changed) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index d36ae627066..afbee184690 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -67,7 +67,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // Returns true if the service config has changed since the last result. typedef bool (*ProcessResolverResultCallback)( void* user_data, Resolver::Result* result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config); + const ParsedLoadBalancingConfig** lb_policy_config, + const HealthCheckParsedObject** health_check); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -106,7 +107,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, - Resolver::Result result, TraceStringVector* trace_strings); + Resolver::Result result, TraceStringVector* trace_strings, + const HealthCheckParsedObject* health_check); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index b38bd4b701e..a0831c117aa 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -532,29 +532,11 @@ BackOff::Options ParseArgsForBackoffValues( .set_max_backoff(max_backoff_ms); } -struct HealthCheckParams { - UniquePtr service_name; - - static void Parse(const grpc_json* field, HealthCheckParams* params) { - if (strcmp(field->key, "healthCheckConfig") == 0) { - if (field->type != GRPC_JSON_OBJECT) return; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) return; - if (strcmp(sub_field->key, "serviceName") == 0) { - if (params->service_name != nullptr) return; // Duplicate. - if (sub_field->type != GRPC_JSON_STRING) return; - params->service_name.reset(gpr_strdup(sub_field->value)); - } - } - } - } -}; - } // namespace Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args) + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) : key_(key), connector_(connector), backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { @@ -586,20 +568,10 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - // Check whether we should enable health checking. - const char* service_config_json = grpc_channel_arg_get_string( - grpc_channel_args_find(args_, GRPC_ARG_SERVICE_CONFIG)); - if (service_config_json != nullptr) { - grpc_error* service_config_error = GRPC_ERROR_NONE; - RefCountedPtr service_config = - ServiceConfig::Create(service_config_json, &service_config_error); - // service_config_error is currently unused. - GRPC_ERROR_UNREF(service_config_error); - if (service_config != nullptr) { - HealthCheckParams params; - service_config->ParseGlobalParams(HealthCheckParams::Parse, ¶ms); - health_check_service_name_ = std::move(params.service_name); - } + + if (health_check != nullptr) { + health_check_service_name_ = + UniquePtr(gpr_strdup(health_check->service_name())); } const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); const bool channelz_enabled = @@ -635,7 +607,8 @@ Subchannel::~Subchannel() { } Subchannel* Subchannel::Create(grpc_connector* connector, - const grpc_channel_args* args) { + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) { SubchannelKey* key = New(args); SubchannelPoolInterface* subchannel_pool = SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); @@ -645,7 +618,7 @@ Subchannel* Subchannel::Create(grpc_connector* connector, Delete(key); return c; } - c = New(key, connector, args); + c = New(key, connector, args, health_check); // Try to register the subchannel before setting the subchannel pool. // Otherwise, in case of a registration race, unreffing c in // RegisterSubchannel() will cause c to be tried to be unregistered, while diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index 83b57dd7ff3..05bbf4585a3 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,6 +23,7 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" @@ -178,12 +179,14 @@ class Subchannel { public: // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args); + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check); ~Subchannel(); // Creates a subchannel given \a connector and \a args. static Subchannel* Create(grpc_connector* connector, - const grpc_channel_args* args); + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check); // Strong and weak refcounting. Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 26c78241b70..73579457065 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -127,7 +127,6 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } void MessageSizeParser::Register() { - gpr_log(GPR_ERROR, "registered"); message_size_parser_index = ServiceConfig::RegisterParser( UniquePtr(New())); } diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index 0d61abd2a01..ca5a7458e8d 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -37,11 +37,13 @@ namespace grpc_core { class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) override { grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); grpc_connector* connector = grpc_chttp2_connector_create(); - Subchannel* s = Subchannel::Create(connector, new_args); + Subchannel* s = Subchannel::Create(connector, new_args, health_check); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index bc38ff25c79..c10d1903dd4 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -44,7 +44,9 @@ namespace grpc_core { class Chttp2SecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel(const grpc_channel_args* args) override { + Subchannel* CreateSubchannel( + const grpc_channel_args* args, + const HealthCheckParsedObject* health_check) override { grpc_channel_args* new_args = GetSecureNamingChannelArgs(args); if (new_args == nullptr) { gpr_log(GPR_ERROR, @@ -52,7 +54,7 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory { return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - Subchannel* s = Subchannel::Create(connector, new_args); + Subchannel* s = Subchannel::Create(connector, new_args, health_check); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 05e25eb08bc..42dd9b38960 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -141,8 +141,11 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy InterceptRecvTrailingMetadataCallback cb, void* user_data) : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} - Subchannel* CreateSubchannel(const grpc_channel_args& args) override { - return parent_->channel_control_helper()->CreateSubchannel(args); + Subchannel* CreateSubchannel( + const grpc_channel_args& args, + const HealthCheckParsedObject* health_check) override { + return parent_->channel_control_helper()->CreateSubchannel(args, + health_check); } grpc_channel* CreateChannel(const char* target, diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index a11b55eb90c..b9a4324a2d3 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -30,6 +30,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" @@ -321,7 +322,8 @@ static void DoNothing(void* arg, grpc_error* error) {} class FakeClientChannelFactory : public grpc_core::ClientChannelFactory { public: grpc_core::Subchannel* CreateSubchannel( - const grpc_channel_args* args) override { + const grpc_channel_args* args, + const grpc_core::HealthCheckParsedObject* health_check) override { return nullptr; } grpc_channel* CreateChannel(const char* target, From 576828696ad6d9be4d36de4802ad5998eec4b92a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 18 Apr 2019 19:51:12 -0700 Subject: [PATCH 027/112] Add parsing tests --- .../ext/filters/client_channel/lb_policy.cc | 41 +- .../ext/filters/client_channel/lb_policy.h | 1 + .../client_channel/lb_policy/grpclb/grpclb.cc | 2 +- .../client_channel/lb_policy/xds/xds.cc | 4 +- .../client_channel/lb_policy_registry.cc | 10 +- .../client_channel/lb_policy_registry.h | 2 +- .../client_channel/resolver_result_parsing.cc | 29 +- .../filters/client_channel/service_config.cc | 22 +- .../message_size/message_size_filter.cc | 91 +-- .../message_size/message_size_filter.h | 19 + .../client_channel/service_config_test.cc | 659 +++++++++++++++++- 11 files changed, 748 insertions(+), 132 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index cd6397a4ae2..19142e3f3b7 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -63,41 +63,51 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, } grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( - const grpc_json* lb_config_array, grpc_error** error) { + const grpc_json* lb_config_array, const char* field_name, + grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + char* error_msg; if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:type should be array"); + gpr_asprintf(&error_msg, "field:%s error:type should be array", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } // Find the first LB policy that this client supports. for (const grpc_json* lb_config = lb_config_array->child; lb_config != nullptr; lb_config = lb_config->next) { if (lb_config->type != GRPC_JSON_OBJECT) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:child entry should be of type " - "object"); + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } grpc_json* policy = nullptr; for (grpc_json* field = lb_config->child; field != nullptr; field = field->next) { if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:child entry should be of type " - "object"); + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } if (policy != nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:oneOf violation"); + gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } // Violate "oneof" type. policy = field; } if (policy == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:no policy found in child entry"); + gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } // If we support this policy, then select it. @@ -105,8 +115,9 @@ grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( return policy; } } - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig error:No known policy"); + gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); return nullptr; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index a8857e9b6a7..a0479b51de3 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -276,6 +276,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// Returns the JSON node of policy (with both policy name and config content) /// given the JSON node of a LoadBalancingConfig array. static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array, + const char* field_name, grpc_error** error); // A picker that returns PICK_QUEUE for all picks. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 8e2dbfa8d5d..9c82a1bbbe6 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1860,7 +1860,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, &parse_error); + field, "childPolicy", &parse_error); if (parse_error != GRPC_ERROR_NONE) { error_list.push_back(parse_error); } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 804417c177e..e9b86405d93 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1728,7 +1728,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, &parse_error); + field, "childPolicy", &parse_error); if (child_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); @@ -1740,7 +1740,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, &parse_error); + field, "fallbackPolicy", &parse_error); if (fallback_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index e22a0a793de..f4cc115eefc 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -101,11 +101,12 @@ bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { UniquePtr LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, + const char* field_name, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); GPR_ASSERT(g_state != nullptr); const grpc_json* policy = - LoadBalancingPolicy::ParseLoadBalancingConfig(json, error); + LoadBalancingPolicy::ParseLoadBalancingConfig(json, field_name, error); if (policy == nullptr) { return nullptr; } else { @@ -114,8 +115,11 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, LoadBalancingPolicyFactory* factory = g_state->GetLoadBalancingPolicyFactory(policy->key); if (factory == nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingConfig entry:Factory not found to create policy"); + char* msg; + gpr_asprintf(&msg, "field:%s error:Factory not found to create policy", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); return nullptr; } // Parse load balancing config via factory. diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index af85e511fbb..8ac845c59f1 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -53,7 +53,7 @@ class LoadBalancingPolicyRegistry { static bool LoadBalancingPolicyExists(const char* name); static UniquePtr ParseLoadBalancingConfig( - const grpc_json* json, grpc_error** error); + const grpc_json* json, const char* field_name, grpc_error** error); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 60b6288296a..54b90cd4039 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -61,23 +61,6 @@ ProcessedResolverResult::ProcessedResolverResult( // Error is currently unused. GRPC_ERROR_UNREF(error); } - } else { - // Add the service config JSON to channel args so that it's - // accessible in the subchannel. - // TODO(roth): Consider whether there's a better way to pass the - // service config down into the subchannel stack, such as maybe via - // call context or metadata. This would avoid the problem of having - // to recreate all subchannels whenever the service config changes. - // It would also avoid the need to pass in the resolver result in - // mutable form, both here and in - // ResolvingLoadBalancingPolicy::ProcessResolverResultCallback(). - grpc_arg arg = grpc_channel_arg_string_create( - const_cast(GRPC_ARG_SERVICE_CONFIG), - const_cast(service_config_->service_config_json())); - grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(resolver_result->args, &arg, 1); - grpc_channel_args_destroy(resolver_result->args); - resolver_result->args = new_args; } // Process service config. ProcessServiceConfig(*resolver_result, parse_retry); @@ -380,8 +363,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } else { grpc_error* parse_error = GRPC_ERROR_NONE; parsed_lb_config = - LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, - &parse_error); + LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, "loadBalancingConfig", &parse_error); if (parsed_lb_config == nullptr) { error_list.push_back(parse_error); } @@ -398,7 +381,11 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } else if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( field->value)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:Unrecognized lb policy")); + "field:loadBalancingPolicy error:Unknown lb policy")); + } else if (strcmp(field->value, "xds_experimental") == 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:xds not supported with this " + "field. Please use loadBalancingConfig")); } else { lb_policy_name = field->value; } @@ -535,7 +522,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, wait_for_ready.set(false); } else { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:waitForReady error:Type should be a true/false")); + "field:waitForReady error:Type should be true/false")); } } else if (strcmp(field->key, "timeout") == 0) { if (timeout > 0) { diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 06a413a89af..9a246785820 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -37,7 +37,7 @@ namespace { typedef InlinedVector, ServiceConfig::kNumPreallocatedParsers> ServiceConfigParserList; -ServiceConfigParserList* registered_parsers; +ServiceConfigParserList* g_registered_parsers; // Consumes all the errors in the vector and forms a referencing error from // them. If the vector is empty, return GRPC_ERROR_NONE. @@ -107,10 +107,10 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { GPR_DEBUG_ASSERT(json_tree_->type == GRPC_JSON_OBJECT); GPR_DEBUG_ASSERT(json_tree_->key == nullptr); InlinedVector error_list; - for (size_t i = 0; i < registered_parsers->size(); i++) { + for (size_t i = 0; i < g_registered_parsers->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error); + (*g_registered_parsers)[i]->ParseGlobalParams(json_tree, &parser_error); if (parser_error != GRPC_ERROR_NONE) { error_list.push_back(parser_error); } @@ -125,10 +125,10 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( size_t* idx) { auto objs_vector = MakeUnique(); InlinedVector error_list; - for (size_t i = 0; i < registered_parsers->size(); i++) { + for (size_t i = 0; i < g_registered_parsers->size(); i++) { grpc_error* parser_error = GRPC_ERROR_NONE; auto parsed_obj = - (*registered_parsers)[i]->ParsePerMethodParams(json, &parser_error); + (*g_registered_parsers)[i]->ParsePerMethodParams(json, &parser_error); if (parser_error != GRPC_ERROR_NONE) { error_list.push_back(parser_error); } @@ -332,18 +332,18 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { } size_t ServiceConfig::RegisterParser(UniquePtr parser) { - registered_parsers->push_back(std::move(parser)); - return registered_parsers->size() - 1; + g_registered_parsers->push_back(std::move(parser)); + return g_registered_parsers->size() - 1; } void ServiceConfig::Init() { - GPR_ASSERT(registered_parsers == nullptr); - registered_parsers = New(); + GPR_ASSERT(g_registered_parsers == nullptr); + g_registered_parsers = New(); } void ServiceConfig::Shutdown() { - Delete(registered_parsers); - registered_parsers = nullptr; + Delete(g_registered_parsers); + g_registered_parsers = nullptr; } } // namespace grpc_core diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 73579457065..146cb5d23f3 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -35,11 +35,6 @@ #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel_init.h" -typedef struct { - int max_send_size; - int max_recv_size; -} message_size_limits; - namespace { size_t message_size_parser_index; @@ -64,19 +59,6 @@ grpc_error* CreateErrorFromVector( namespace grpc_core { -class MessageSizeParsedObject : public ServiceConfigParsedObject { - public: - MessageSizeParsedObject(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - const message_size_limits& limits() const { return limits_; } - - private: - message_size_limits limits_; -}; - UniquePtr MessageSizeParser::ParsePerMethodParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); @@ -89,32 +71,32 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_request_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:Duplicate entry")); - continue; - } - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:should be of type number")); - continue; - } - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be non-negative")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } } } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + gpr_log(GPR_ERROR, "bla"); if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); - continue; - } - if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:should be of type number")); - } - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be non-negative")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } } } } @@ -132,25 +114,6 @@ void MessageSizeParser::Register() { } size_t MessageSizeParser::ParserIndex() { return message_size_parser_index; } - -class MessageSizeLimits : public RefCounted { - public: - static RefCountedPtr CreateFromJson(const grpc_json* json); - - const message_size_limits& limits() const { return limits_; } - - private: - // So New() can call our private ctor. - template - friend T* grpc_core::New(Args&&... args); - - MessageSizeLimits(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - message_size_limits limits_; -}; } // namespace grpc_core static void recv_message_ready(void* user_data, grpc_error* error); @@ -159,12 +122,8 @@ static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); namespace { struct channel_data { - message_size_limits limits; + grpc_core::MessageSizeParsedObject::message_size_limits limits; grpc_core::RefCountedPtr svc_cfg; - // Maps path names to refcounted_message_size_limits structs. - grpc_core::RefCountedPtr>> - method_limit_table; }; struct call_data { @@ -213,7 +172,7 @@ struct call_data { ~call_data() { GRPC_ERROR_UNREF(error); } grpc_call_combiner* call_combiner; - message_size_limits limits; + grpc_core::MessageSizeParsedObject::message_size_limits limits; // Receive closures are chained: we inject this closure as the // recv_message_ready up-call on transport_stream_op, and remember to // call our next_recv_message_ready member after handling it. @@ -359,9 +318,9 @@ static int default_size(const grpc_channel_args* args, return without_minimal_stack; } -message_size_limits get_message_size_limits( +grpc_core::MessageSizeParsedObject::message_size_limits get_message_size_limits( const grpc_channel_args* channel_args) { - message_size_limits lim; + grpc_core::MessageSizeParsedObject::message_size_limits lim; lim.max_send_size = default_size(channel_args, GRPC_DEFAULT_MAX_SEND_MESSAGE_LENGTH); lim.max_recv_size = @@ -409,10 +368,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, } // Destructor for channel_data. -static void destroy_channel_elem(grpc_channel_element* elem) { - channel_data* chand = static_cast(elem->channel_data); - chand->method_limit_table.reset(); -} +static void destroy_channel_elem(grpc_channel_element* elem) {} const grpc_channel_filter grpc_message_size_filter = { start_transport_stream_op_batch, @@ -441,7 +397,8 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, const grpc_channel_args* channel_args = grpc_channel_stack_builder_get_channel_arguments(builder); bool enable = false; - message_size_limits lim = get_message_size_limits(channel_args); + grpc_core::MessageSizeParsedObject::message_size_limits lim = + get_message_size_limits(channel_args); if (lim.max_send_size != -1 || lim.max_recv_size != -1) { enable = true; } diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index 6f0f16ab67c..a4aa79f70ac 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -25,6 +25,25 @@ extern const grpc_channel_filter grpc_message_size_filter; namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + class MessageSizeParser : public ServiceConfigParser { public: UniquePtr ParsePerMethodParams( diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 229944435b0..be86400e32d 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -21,8 +21,10 @@ #include #include +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -153,8 +155,10 @@ TEST_F(ServiceConfigTest, ErrorCheck1) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - EXPECT_TRUE(strstr(grpc_error_string(error), - "failed to parse JSON for service config") != nullptr); + std::regex e(std::string("failed to parse JSON for service config")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } @@ -171,7 +175,15 @@ TEST_F(ServiceConfigTest, ErrorNoNames) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - EXPECT_TRUE(strstr(grpc_error_string(error), "No names found") != nullptr); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " + "names specified)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } @@ -182,7 +194,15 @@ TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - EXPECT_TRUE(strstr(grpc_error_string(error), "No names found") != nullptr); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(No names " + "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " + "names specified)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } @@ -225,7 +245,7 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { ASSERT_TRUE(error != GRPC_ERROR_NONE); std::regex e(std::string("(Service config parsing " "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + + "Params)(.*)(referenced_errors)(.*)") + TestParser1::InvalidTypeErrorMessage()); std::smatch match; std::string s(grpc_error_string(error)); @@ -241,7 +261,7 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { ASSERT_TRUE(error != GRPC_ERROR_NONE); std::regex e(std::string("(Service config parsing " "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + + "Params)(.*)(referenced_errors)(.*)") + TestParser1::InvalidValueErrorMessage()); std::smatch match; std::string s(grpc_error_string(error)); @@ -273,7 +293,7 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); std::regex e(std::string("(Service config parsing " "error)(.*)(referenced_errors\":\\[)(.*)(Method " - "Params)(.*)(referenced_errors)()(.*)(methodConfig)(" + "Params)(.*)(referenced_errors)(.*)(methodConfig)(" ".*)(referenced_errors)(.*)") + TestParser2::InvalidTypeErrorMessage()); std::smatch match; @@ -367,7 +387,7 @@ class ClientChannelParserTest : public ::testing::Test { } }; -TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig1) { +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) { const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); @@ -379,7 +399,7 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig1) { EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); } -TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig2) { +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { const char* test_json = "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; grpc_error* error = GRPC_ERROR_NONE; @@ -392,13 +412,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig2) { EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); } -TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig3) { +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { const char* test_json = "{\"loadBalancingConfig\": " "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error == GRPC_ERROR_NONE); const auto* parsed_object = static_cast( @@ -407,6 +426,624 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfig3) { EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); } +TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { + const char* test_json = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{ \"balancerName\": \"fake:///lb\" } }\n" + " ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_config = parsed_object->parsed_lb_config(); + EXPECT_TRUE(strcmp(lb_config->name(), "xds_experimental") == 0); +} + +TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) { + const char* test_json = "{\"loadBalancingConfig\": [{\"unknown\":{}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingConfig error:No known policy)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidgRPCLbLoadBalancingConfig) { + const char* test_json = + "{\"loadBalancingConfig\": " + "[{\"grpclb\":{\"childPolicy\":[{\"unknown\":{}}]}}]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(GrpcLb " + "Parser)(.*)(referenced_errors)(.*)(field:childPolicy " + "error:No known policy)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InalidLoadBalancingConfigXds) { + const char* test_json = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"does_not_exist\":{} },\n" + " { \"xds_experimental\":{} }\n" + " ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(Xds " + "Parser)(.*)(referenced_errors)(.*)(field:balancerName " + "error:not found)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { + const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_policy = parsed_object->parsed_deprecated_lb_policy(); + ASSERT_TRUE(lb_policy != nullptr); + EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); +} + +TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { + const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:Unknown lb policy)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { + const char* test_json = "{\"loadBalancingPolicy\":\"xds_experimental\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:xds not supported)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidRetryThrottling) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": 1.0\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto retryThrottling = parsed_object->retry_throttling(); + ASSERT_TRUE(retryThrottling.has_value()); + EXPECT_EQ(retryThrottling.value().max_milli_tokens, 2000); + EXPECT_EQ(retryThrottling.value().milli_token_ratio, 1000); +} + +TEST_F(ClientChannelParserTest, RetryThrottlingMissingFields) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:maxTokens error:Not found)(.*)(field:retryThrottling " + "field:tokenRatio error:Not found)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": -2,\n" + " \"tokenRatio\": 1.0\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:maxTokens error:should be greater than zero)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { + const char* test_json = + "{\n" + " \"retryThrottling\": {\n" + " \"maxTokens\": 2,\n" + " \"tokenRatio\": -1\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " + "field:tokenRatio error:Failed parsing)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidTimeout) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"timeout\": \"5s\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[0]).get(); + EXPECT_EQ((static_cast( + parsed_object)) + ->timeout(), + 5000); +} + +TEST_F(ClientChannelParserTest, InvalidTimeout) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"timeout\": \"5sec\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(field:timeout " + "error:Failed parsing)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidWaitForReady) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"waitForReady\": true\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = ((*vector_ptr)[0]).get(); + EXPECT_TRUE( + (static_cast( + parsed_object)) + ->wait_for_ready() + .has_value()); + EXPECT_TRUE( + (static_cast( + parsed_object)) + ->wait_for_ready() + .value()); +} + +TEST_F(ClientChannelParserTest, InvalidWaitForReady) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"waitForReady\": \"true\"\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(field:waitForReady " + "error:Type should be true/false)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, ValidRetryPolicy) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + const auto* parsed_object = + static_cast( + ((*vector_ptr)[0]).get()); + EXPECT_TRUE(parsed_object->retry_policy() != nullptr); + EXPECT_EQ(parsed_object->retry_policy()->max_attempts, 3); + EXPECT_EQ(parsed_object->retry_policy()->initial_backoff, 1000); + EXPECT_EQ(parsed_object->retry_policy()->max_backoff, 120000); + EXPECT_EQ(parsed_object->retry_policy()->backoff_multiplier, 1.6f); + EXPECT_TRUE(parsed_object->retry_policy()->retryable_status_codes.Contains( + GRPC_STATUS_ABORTED)); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxAttempts) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:maxAttempts error:should be atleast 2)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1sec\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:initialBackoff error:Failed to parse)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:maxBackoff error:failed to parse)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": \"1.6\",\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:backoffMultiplier error:should be of type number)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 1,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120sec\",\n" + " \"backoffMultiplier\": \"1.6\",\n" + " \"retryableStatusCodes\": []\n" + " }\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" + ".*)(Client channel " + "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." + "*)(field:retryableStatusCodes error:should be non-empty)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +class MessageSizeParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + New())) == 0); + } +}; + +TEST_F(MessageSizeParserTest, Valid) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": 1024,\n" + " \"maxResponseMessageBytes\": 1024\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* vector_ptr = svc_cfg->GetMethodServiceConfigObjectsVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + EXPECT_TRUE(vector_ptr != nullptr); + auto parsed_object = + static_cast(((*vector_ptr)[0]).get()); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(parsed_object->limits().max_send_size, 1024); + EXPECT_EQ(parsed_object->limits().max_recv_size, 1024); +} + +TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": -1024\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Message size " + "parser)(.*)(referenced_errors)(.*)(field:" + "maxRequestMessageBytes error:should be non-negative)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + +TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { + const char* test_json = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"TestServ\", \"method\": \"TestMethod\" }\n" + " ],\n" + " \"maxResponseMessageBytes\": {}\n" + " } ]\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Method " + "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" + "referenced_errors)(.*)(Message size " + "parser)(.*)(referenced_errors)(.*)(field:" + "maxResponseMessageBytes error:should be of type number)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} } // namespace testing } // namespace grpc_core From 2f2899203bd1059f47aea91d5ddccc0611f44b79 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 19 Apr 2019 09:41:23 -0700 Subject: [PATCH 028/112] Make cares resolver opt-in with libuv --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index 3f1a700c3d6..ee7929b8d39 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -429,10 +429,18 @@ static grpc_error* blocking_resolve_address_ares( static grpc_address_resolver_vtable ares_resolver = { grpc_resolve_address_ares, blocking_resolve_address_ares}; +#ifdef GRPC_UV +/* TODO(murgatroid99): Remove this when we want the cares resolver to be the + * default when using libuv */ +static bool should_use_ares(const char* resolver_env) { + return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; +} +#else /* GRPC_UV */ static bool should_use_ares(const char* resolver_env) { return resolver_env == nullptr || strlen(resolver_env) == 0 || gpr_stricmp(resolver_env, "ares") == 0; } +#endif /* GRPC_UV */ void grpc_resolver_dns_ares_init() { char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER"); From a36040d51c5f413a8987a508a60527e897531ece Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 19 Apr 2019 10:25:45 -0700 Subject: [PATCH 029/112] Clang format --- .../resolver/dns/c_ares/dns_resolver_ares.cc | 2 +- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 22 +++++++++---------- .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 6 ++--- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index ee7929b8d39..ec662b1416d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -435,7 +435,7 @@ static grpc_address_resolver_vtable ares_resolver = { static bool should_use_ares(const char* resolver_env) { return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0; } -#else /* GRPC_UV */ +#else /* GRPC_UV */ static bool should_use_ares(const char* resolver_env) { return resolver_env == nullptr || strlen(resolver_env) == 0 || gpr_stricmp(resolver_env, "ares") == 0; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index fd09d899187..6993edf8a01 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -36,22 +36,18 @@ namespace grpc_core { void ares_uv_poll_cb(uv_poll_t* handle, int status, int events); -void ares_uv_poll_close_cb(uv_handle_t *handle) { - Delete(handle); -} +void ares_uv_poll_close_cb(uv_handle_t* handle) { Delete(handle); } class GrpcPolledFdLibuv : public GrpcPolledFd { public: - GrpcPolledFdLibuv(ares_socket_t as): as_(as) { + GrpcPolledFdLibuv(ares_socket_t as) : as_(as) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); handle_->data = this; } - ~GrpcPolledFdLibuv() { - gpr_free(name_); - } + ~GrpcPolledFdLibuv() { gpr_free(name_); } void RegisterForOnReadableLocked(grpc_closure* read_closure) override { GPR_ASSERT(read_closure_ == nullptr); @@ -94,12 +90,14 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { grpc_core::ExecCtx exec_ctx; - GrpcPolledFdLibuv* polled_fd = reinterpret_cast(handle->data); - grpc_error *error = GRPC_ERROR_NONE; + GrpcPolledFdLibuv* polled_fd = + reinterpret_cast(handle->data); + grpc_error* error = GRPC_ERROR_NONE; if (status < 0) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); - error = grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, - grpc_slice_from_static_string(uv_strerror(status))); + error = + grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, + grpc_slice_from_static_string(uv_strerror(status))); } if ((events & UV_READABLE) && polled_fd->read_closure_) { GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); @@ -129,6 +127,6 @@ UniquePtr NewGrpcPolledFdFactory(grpc_combiner* combiner) { return UniquePtr(New()); } -} // namespace grpc_core +} // namespace grpc_core #endif /* GRPC_ARES == 1 && defined(GRPC_UV) */ \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index eb8d7e5e900..08f3d9ce30d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -29,11 +29,11 @@ #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" -bool grpc_ares_query_ipv6() { +bool grpc_ares_query_ipv6() { /* The libuv grpc code currently does not have the code to probe for this, - * so we assume for nowthat IPv6 is always available in contexts where this + * so we assume for now that IPv6 is always available in contexts where this * code will be used. */ - return true; + return true; } /* The following two functions were copied entirely from the Windows file. This From 1ab9ffe5c030b88bd10f70d7bab3cff6ffd0e7a9 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 11:34:19 -0700 Subject: [PATCH 030/112] Do not add message size filter for minimal stack --- .../message_size/message_size_filter.cc | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index 146cb5d23f3..dca3f2e2fd2 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -368,7 +368,10 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, } // Destructor for channel_data. -static void destroy_channel_elem(grpc_channel_element* elem) {} +static void destroy_channel_elem(grpc_channel_element* elem) { + channel_data* chand = static_cast(elem->channel_data); + chand->svc_cfg.reset(); +} const grpc_channel_filter grpc_message_size_filter = { start_transport_stream_op_batch, @@ -384,8 +387,13 @@ const grpc_channel_filter grpc_message_size_filter = { "message_size"}; // Used for GRPC_CLIENT_SUBCHANNEL -static bool add_message_size_filter(grpc_channel_stack_builder* builder, - void* arg) { +static bool maybe_add_message_size_filter_subchannel( + grpc_channel_stack_builder* builder, void* arg) { + const grpc_channel_args* channel_args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (grpc_channel_args_want_minimal_stack(channel_args)) { + return true; + } return grpc_channel_stack_builder_prepend_filter( builder, &grpc_message_size_filter, nullptr, nullptr); } @@ -417,9 +425,9 @@ static bool maybe_add_message_size_filter(grpc_channel_stack_builder* builder, } void grpc_message_size_filter_init(void) { - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, - add_message_size_filter, nullptr); + grpc_channel_init_register_stage( + GRPC_CLIENT_SUBCHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, + maybe_add_message_size_filter_subchannel, nullptr); grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); From 3b65effb826a26dd474408a04602b3017b6d719f Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 12:42:40 -0700 Subject: [PATCH 031/112] Cleanup --- .../health/health_check_parser.cc | 8 ++++---- .../client_channel/lb_policy/grpclb/grpclb.cc | 10 ++++------ .../lb_policy/pick_first/pick_first.cc | 10 +--------- .../lb_policy/round_robin/round_robin.cc | 10 +--------- .../filters/client_channel/lb_policy/xds/xds.cc | 15 +++++---------- .../client_channel/resolver_result_parsing.cc | 17 +++++++++++++++-- .../client_channel/resolver_result_parsing.h | 14 ++------------ .../filters/message_size/message_size_filter.cc | 1 - 8 files changed, 32 insertions(+), 53 deletions(-) diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc index b9ccc3cb3b6..1dcef527861 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -22,7 +22,7 @@ namespace grpc_core { namespace { -size_t health_check_parser_index; +size_t g_health_check_parser_index; } UniquePtr HealthCheckParser::ParseGlobalParams( @@ -66,10 +66,10 @@ UniquePtr HealthCheckParser::ParseGlobalParams( } void HealthCheckParser::Register() { - health_check_parser_index = ServiceConfig::RegisterParser( + g_health_check_parser_index = ServiceConfig::RegisterParser( UniquePtr(New())); } -size_t HealthCheckParser::ParserIndex() { return health_check_parser_index; } +size_t HealthCheckParser::ParserIndex() { return g_health_check_parser_index; } -} // namespace grpc_core \ No newline at end of file +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 2146f0620e0..a4c28d8d431 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -120,19 +120,16 @@ constexpr char kGrpclb[] = "grpclb"; class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { public: - ParsedGrpcLbConfig(UniquePtr child_policy, - const grpc_json* json) - : child_policy_(std::move(child_policy)), json_(json) {} + ParsedGrpcLbConfig(UniquePtr child_policy) + : child_policy_(std::move(child_policy)) {} const char* name() const override { return kGrpclb; } const ParsedLoadBalancingConfig* child_policy() const { return child_policy_.get(); } - const grpc_json* config() const { return json_; } private: UniquePtr child_policy_; - const grpc_json* json_ = nullptr; }; class GrpcLb : public LoadBalancingPolicy { @@ -1847,6 +1844,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { if (child_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:childPolicy error:Duplicate entry")); + continue; } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( @@ -1858,7 +1856,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } if (error_list.empty()) { return UniquePtr( - New(std::move(child_policy), json)); + New(std::move(child_policy))); } else { *error = CreateErrorFromVector("GrpcLb Parser", &error_list); return nullptr; diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 9e9f9bbdb91..21fda23ab71 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -530,14 +530,7 @@ void PickFirst::PickFirstSubchannelData:: class ParsedPickFirstConfig : public ParsedLoadBalancingConfig { public: - ParsedPickFirstConfig(const grpc_json* json) : json_(json) {} - const char* name() const override { return kPickFirst; } - - const grpc_json* config() const { return json_; } - - private: - const grpc_json* json_; }; // @@ -557,8 +550,7 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(json != nullptr); GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); - return UniquePtr( - New(json)); + return UniquePtr(New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 6fe007a9796..193e383a433 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -507,14 +507,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { class ParsedRoundRobinConfig : public ParsedLoadBalancingConfig { public: - ParsedRoundRobinConfig(const grpc_json* json) : json_(json) {} - const char* name() const override { return kRoundRobin; } - - const grpc_json* config() const { return json_; } - - private: - const grpc_json* json_; }; // @@ -534,8 +527,7 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(json != nullptr); GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); - return UniquePtr( - New(json)); + return UniquePtr(New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 0368c8dbb30..7d222558f4d 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -123,12 +123,10 @@ class ParsedXdsConfig : public ParsedLoadBalancingConfig { public: ParsedXdsConfig(const char* balancer_name, UniquePtr child_policy, - UniquePtr fallback_policy, - const grpc_json* json) + UniquePtr fallback_policy) : balancer_name_(balancer_name), child_policy_(std::move(child_policy)), - fallback_policy_(std::move(fallback_policy)), - json_(json) {} + fallback_policy_(std::move(fallback_policy)) {} const char* name() const override { return kXds; } @@ -142,13 +140,10 @@ class ParsedXdsConfig : public ParsedLoadBalancingConfig { return fallback_policy_.get(); } - const grpc_json* config() const { return json_; } - private: const char* balancer_name_ = nullptr; UniquePtr child_policy_; UniquePtr fallback_policy_; - const grpc_json* json_ = nullptr; }; class XdsLb : public LoadBalancingPolicy { @@ -1729,6 +1724,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (fallback_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:fallbackPolicy error:Duplicate entry")); + continue; } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( @@ -1744,9 +1740,8 @@ class XdsFactory : public LoadBalancingPolicyFactory { "field:balancerName error:not found")); } if (error_list.empty()) { - return UniquePtr( - New(balancer_name, std::move(child_policy), - std::move(fallback_policy), json)); + return UniquePtr(New( + balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { *error = CreateErrorFromVector("Xds Parser", &error_list); return nullptr; diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 54b90cd4039..1756917b391 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -44,8 +44,19 @@ namespace grpc_core { namespace internal { -size_t ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index_; +namespace { +size_t g_client_channel_service_config_parser_index; +} + +size_t +ClientChannelServiceConfigParser::client_channel_service_config_parser_index() { + return g_client_channel_service_config_parser_index; +} + +void ClientChannelServiceConfigParser::Register() { + g_client_channel_service_config_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} ProcessedResolverResult::ProcessedResolverResult( Resolver::Result* resolver_result, bool parse_retry) @@ -333,6 +344,8 @@ UniquePtr ParseRetryPolicy( retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 || retry_policy->retryable_status_codes.Empty()) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryPolicy error:Missing required field(s)"); return nullptr; } } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 6e73c43a779..327818f668d 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -107,18 +107,8 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser { UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override; - static size_t client_channel_service_config_parser_index() { - return client_channel_service_config_parser_index_; - } - - static void Register() { - client_channel_service_config_parser_index_ = - ServiceConfig::RegisterParser(UniquePtr( - New())); - } - - private: - static size_t client_channel_service_config_parser_index_; + static size_t client_channel_service_config_parser_index(); + static void Register(); }; // A container of processed fields from the resolver result. Simplifies the diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index dca3f2e2fd2..ac1984f6929 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -83,7 +83,6 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } } } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - gpr_log(GPR_ERROR, "bla"); if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); From 07e899f5f3fbb9cc8c0831cc867cf0466780664a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 14:15:59 -0700 Subject: [PATCH 032/112] Separate out message size parsing into a different file to avoid build issues --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 6 ++ Makefile | 6 ++ build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 4 + package.xml | 2 + .../client_channel/client_channel_plugin.cc | 2 +- .../message_size/message_size_filter.cc | 96 ++--------------- .../message_size/message_size_filter.h | 31 ------ .../message_size/message_size_parser.cc | 101 ++++++++++++++++++ .../message_size/message_size_parser.h | 55 ++++++++++ src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 7 +- 20 files changed, 206 insertions(+), 121 deletions(-) create mode 100644 src/core/ext/filters/message_size/message_size_parser.cc create mode 100644 src/core/ext/filters/message_size/message_size_parser.h diff --git a/BUILD b/BUILD index 7f99bcdfaca..07db0019138 100644 --- a/BUILD +++ b/BUILD @@ -1099,6 +1099,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/service_config.cc", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", + "src/core/ext/filters/message_size/message_size_parser.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1128,6 +1129,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/message_size/message_size_parser.h", ], language = "c++", deps = [ diff --git a/BUILD.gn b/BUILD.gn index e83def5507d..d75dce49080 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -354,6 +354,8 @@ config("grpc_config") { "src/core/ext/filters/max_age/max_age_filter.h", "src/core/ext/filters/message_size/message_size_filter.cc", "src/core/ext/filters/message_size/message_size_filter.h", + "src/core/ext/filters/message_size/message_size_parser.cc", + "src/core/ext/filters/message_size/message_size_parser.h", "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc", "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h", "src/core/ext/filters/workarounds/workaround_utils.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index b221b4e7cd1..56ccbffd0c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1252,6 +1252,7 @@ add_library(grpc src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/fake_transport_security.cc @@ -1608,6 +1609,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -1989,6 +1991,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2315,6 +2318,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2652,6 +2656,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -3523,6 +3528,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc + src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc diff --git a/Makefile b/Makefile index 4f9acb9fc1f..1b371a8431f 100644 --- a/Makefile +++ b/Makefile @@ -3708,6 +3708,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ @@ -4058,6 +4059,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4432,6 +4434,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4745,6 +4748,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5056,6 +5060,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5903,6 +5908,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \ diff --git a/build.yaml b/build.yaml index a180c8c1d28..936cd911b31 100644 --- a/build.yaml +++ b/build.yaml @@ -596,6 +596,7 @@ filegroups: - src/core/ext/filters/client_channel/service_config.h - src/core/ext/filters/client_channel/subchannel.h - src/core/ext/filters/client_channel/subchannel_pool_interface.h + - src/core/ext/filters/message_size/message_size_parser.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -624,6 +625,7 @@ filegroups: - src/core/ext/filters/client_channel/service_config.cc - src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_pool_interface.cc + - src/core/ext/filters/message_size/message_size_parser.cc plugin: grpc_client_channel uses: - grpc_base diff --git a/config.m4 b/config.m4 index e7d3a5daf4e..0710e1e8341 100644 --- a/config.m4 +++ b/config.m4 @@ -366,6 +366,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ + src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ diff --git a/config.w32 b/config.w32 index 8a6529faae2..e69f71dbfb3 100644 --- a/config.w32 +++ b/config.w32 @@ -341,6 +341,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\service_config.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + + "src\\core\\ext\\filters\\message_size\\message_size_parser.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\fake_transport_security.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 782d86a6fcb..d4f4b626011 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -385,6 +385,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', + 'src/core/ext/filters/message_size/message_size_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 13c2a2cf9d0..aa38487e194 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -367,6 +367,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', + 'src/core/ext/filters/message_size/message_size_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -815,6 +816,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', + 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -1011,6 +1013,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', + 'src/core/ext/filters/message_size/message_size_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/grpc.gemspec b/grpc.gemspec index bca4674c761..9749cc69e47 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -301,6 +301,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/service_config.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) + s.files += %w( src/core/ext/filters/message_size/message_size_parser.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) @@ -752,6 +753,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/service_config.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc ) + s.files += %w( src/core/ext/filters/message_size/message_size_parser.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/fake_transport_security.cc ) diff --git a/grpc.gyp b/grpc.gyp index d4db059dc0a..874cc5a52bf 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -548,6 +548,7 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', + 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -813,6 +814,7 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', + 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1059,6 +1061,7 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', + 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1316,6 +1319,7 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', + 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', diff --git a/package.xml b/package.xml index 3af95c9a727..66bf5ee8863 100644 --- a/package.xml +++ b/package.xml @@ -306,6 +306,7 @@ + @@ -757,6 +758,7 @@ + diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 92b1fed61d1..729043bebfc 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -35,7 +35,7 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/message_size/message_size_filter.h" +#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index ac1984f6929..f3976cb783f 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -26,7 +26,7 @@ #include #include -#include "src/core/ext/filters/client_channel/service_config.h" +#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/gpr/string.h" @@ -35,91 +35,10 @@ #include "src/core/lib/surface/call.h" #include "src/core/lib/surface/channel_init.h" -namespace { -size_t message_size_parser_index; - -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector( - const char* desc, grpc_core::InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} -} // namespace - -namespace grpc_core { - -UniquePtr MessageSizeParser::ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - int max_request_message_bytes = -1; - int max_response_message_bytes = -1; - InlinedVector error_list; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) continue; - if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be of type number")); - } else { - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be non-negative")); - } - } - } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be of type number")); - } else { - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be non-negative")); - } - } - } - } - if (!error_list.empty()) { - *error = CreateErrorFromVector("Message size parser", &error_list); - return nullptr; - } - return UniquePtr(New( - max_request_message_bytes, max_response_message_bytes)); -} - -void MessageSizeParser::Register() { - message_size_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); -} - -size_t MessageSizeParser::ParserIndex() { return message_size_parser_index; } -} // namespace grpc_core - static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); namespace { - struct channel_data { grpc_core::MessageSizeParsedObject::message_size_limits limits; grpc_core::RefCountedPtr svc_cfg; @@ -140,18 +59,21 @@ struct call_data { // size to the receive limit. const grpc_core::MessageSizeParsedObject* limits = nullptr; const grpc_core::ServiceConfig::ServiceConfigObjectsVector* objs_vector = - static_cast< - const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( - args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + nullptr; + if (args.context != nullptr) { + objs_vector = static_cast< + const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( + args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + } if (objs_vector != nullptr) { limits = static_cast( - (*objs_vector)[message_size_parser_index].get()); + (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); } else if (chand.svc_cfg != nullptr) { objs_vector = chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); if (objs_vector != nullptr) { limits = static_cast( - (*objs_vector)[message_size_parser_index].get()); + (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); } } if (limits != nullptr) { diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index a4aa79f70ac..b916bdd83f6 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -24,35 +24,4 @@ extern const grpc_channel_filter grpc_message_size_filter; -namespace grpc_core { - -class MessageSizeParsedObject : public ServiceConfigParsedObject { - public: - struct message_size_limits { - int max_send_size; - int max_recv_size; - }; - - MessageSizeParsedObject(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - const message_size_limits& limits() const { return limits_; } - - private: - message_size_limits limits_; -}; - -class MessageSizeParser : public ServiceConfigParser { - public: - UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) override; - - static void Register(); - - static size_t ParserIndex(); -}; -} // namespace grpc_core - #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/core/ext/filters/message_size/message_size_parser.cc b/src/core/ext/filters/message_size/message_size_parser.cc new file mode 100644 index 00000000000..534082ee6ff --- /dev/null +++ b/src/core/ext/filters/message_size/message_size_parser.cc @@ -0,0 +1,101 @@ +// +// Copyright 2019 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include + +#include "src/core/ext/filters/message_size/message_size_parser.h" + +#include "src/core/lib/gpr/string.h" + +namespace { +size_t g_message_size_parser_index; + +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +grpc_error* CreateErrorFromVector( + const char* desc, grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} +} // namespace + +namespace grpc_core { + +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + InlinedVector error_list; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } + } + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } + } + } + } + if (!error_list.empty()) { + *error = CreateErrorFromVector("Message size parser", &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); +} + +void MessageSizeParser::Register() { + g_message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } +} // namespace grpc_core diff --git a/src/core/ext/filters/message_size/message_size_parser.h b/src/core/ext/filters/message_size/message_size_parser.h new file mode 100644 index 00000000000..4581cdf6226 --- /dev/null +++ b/src/core/ext/filters/message_size/message_size_parser.h @@ -0,0 +1,55 @@ +// +// Copyright 2019 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H +#define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H + +#include + +#include "src/core/ext/filters/client_channel/service_config.h" + +namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + +class MessageSizeParser : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 8060b5a0a8c..6aa0a37826e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -340,6 +340,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', + 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index eee3f777ea6..88e57036830 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -989,6 +989,8 @@ src/core/ext/filters/max_age/max_age_filter.cc \ src/core/ext/filters/max_age/max_age_filter.h \ src/core/ext/filters/message_size/message_size_filter.cc \ src/core/ext/filters/message_size/message_size_filter.h \ +src/core/ext/filters/message_size/message_size_parser.cc \ +src/core/ext/filters/message_size/message_size_parser.h \ src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \ src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h \ src/core/ext/filters/workarounds/workaround_utils.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6a0d47ab932..3b66e146262 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8733,7 +8733,8 @@ "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/message_size/message_size_parser.h" ], "is_filegroup": true, "language": "c", @@ -8792,7 +8793,9 @@ "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", - "src/core/ext/filters/client_channel/subchannel_pool_interface.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h", + "src/core/ext/filters/message_size/message_size_parser.cc", + "src/core/ext/filters/message_size/message_size_parser.h" ], "third_party": false, "type": "filegroup" From a4036b2d8cad28e373ab93922e344d109c1a80d7 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 14:34:37 -0700 Subject: [PATCH 033/112] Add tests for health check parsing too --- .../client_channel/service_config_test.cc | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index be86400e32d..7ea4a88e9bb 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -24,7 +24,7 @@ #include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" -#include "src/core/ext/filters/message_size/message_size_filter.h" +#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -1044,6 +1044,59 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { EXPECT_TRUE(std::regex_search(s, match, e)); GRPC_ERROR_UNREF(error); } + +class HealthCheckParserTest : public ::testing::Test { + protected: + void SetUp() override { + ServiceConfig::Shutdown(); + ServiceConfig::Init(); + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + New())) == 0); + } +}; + +TEST_F(HealthCheckParserTest, Valid) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(strcmp(parsed_object->service_name(), "health_check_service_name"), + 0); +} + +TEST_F(HealthCheckParserTest, MultipleEntries) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " },\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name1\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig " + "field:serviceName error:Duplicate entry)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + } // namespace testing } // namespace grpc_core From baa52808f1e6b4ef3fb62127e989519ad3417e27 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 19 Apr 2019 15:46:16 -0700 Subject: [PATCH 034/112] Use a single copy of CreateErrorFromVector from ServiceConfig --- .../filters/client_channel/client_channel.cc | 3 ++ .../client_channel/lb_policy/grpclb/grpclb.cc | 21 ++------------ .../client_channel/lb_policy/xds/xds.cc | 20 +------------ .../client_channel/resolver_result_parsing.cc | 28 ++++--------------- .../filters/client_channel/service_config.cc | 18 ------------ .../filters/client_channel/service_config.h | 18 ++++++++++++ .../message_size/message_size_parser.cc | 21 ++------------ 7 files changed, 31 insertions(+), 98 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a1029ef67a7..15fe9a8c70a 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -3080,6 +3080,9 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { chand, this); } if (chand->service_config() != nullptr) { + // Store a ref to the service_config in CallData. Also, save pointers to the + // ServiceConfig and ServiceConfigObjectsVector (for this call) in the + // call_context so that all future filters can access it. service_config_ = chand->service_config(); call_context_[GRPC_SERVICE_CONFIG].value = &service_config_; const auto* method_params_vector_ptr = diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index a4c28d8d431..d8e942e6570 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1798,24 +1798,6 @@ void GrpcLb::CreateOrUpdateChildPolicyLocked() { policy_to_update->UpdateLocked(std::move(update_args)); } -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} - // // factory // @@ -1858,7 +1840,8 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { return UniquePtr( New(std::move(child_policy))); } else { - *error = CreateErrorFromVector("GrpcLb Parser", &error_list); + *error = + ServiceConfig::CreateErrorFromVector("GrpcLb Parser", &error_list); return nullptr; } } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 7d222558f4d..7b9c2b320fd 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1652,24 +1652,6 @@ void XdsLb::LocalityMap::LocalityEntry::Helper::RequestReresolution() { } } -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} - // // factory // @@ -1743,7 +1725,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return UniquePtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { - *error = CreateErrorFromVector("Xds Parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Xds Parser", &error_list); return nullptr; } } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 1756917b391..dea8c915856 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -79,26 +79,6 @@ ProcessedResolverResult::ProcessedResolverResult( if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result); } -namespace { -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} -} // namespace - void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, bool parse_retry) { if (service_config_ == nullptr) return; @@ -349,7 +329,7 @@ UniquePtr ParseRetryPolicy( return nullptr; } } - *error = CreateErrorFromVector("retryPolicy", &error_list); + *error = ServiceConfig::CreateErrorFromVector("retryPolicy", &error_list); return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; } @@ -504,7 +484,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } } } - *error = CreateErrorFromVector("Client channel global parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Client channel global parser", + &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( New(std::move(parsed_lb_config), @@ -560,7 +541,8 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, } } } - *error = CreateErrorFromVector("Client channel parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Client channel parser", + &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( New(timeout, wait_for_ready, diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 9a246785820..c6c6af35a68 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -38,24 +38,6 @@ typedef InlinedVector, ServiceConfig::kNumPreallocatedParsers> ServiceConfigParserList; ServiceConfigParserList* g_registered_parsers; - -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector(const char* desc, - InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} } // namespace RefCountedPtr ServiceConfig::Create(const char* json, diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 28e482bf2b7..f45cab9ee7d 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -150,6 +150,24 @@ class ServiceConfig : public RefCounted { static void Shutdown(); + // Consumes all the errors in the vector and forms a referencing error from + // them. If the vector is empty, return GRPC_ERROR_NONE. + template + static grpc_error* CreateErrorFromVector( + const char* desc, InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; + } + private: // So New() can call our private ctor. template diff --git a/src/core/ext/filters/message_size/message_size_parser.cc b/src/core/ext/filters/message_size/message_size_parser.cc index 534082ee6ff..a3444a984dd 100644 --- a/src/core/ext/filters/message_size/message_size_parser.cc +++ b/src/core/ext/filters/message_size/message_size_parser.cc @@ -22,24 +22,6 @@ namespace { size_t g_message_size_parser_index; - -// Consumes all the errors in the vector and forms a referencing error from -// them. If the vector is empty, return GRPC_ERROR_NONE. -template -grpc_error* CreateErrorFromVector( - const char* desc, grpc_core::InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; -} } // namespace namespace grpc_core { @@ -85,7 +67,8 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } } if (!error_list.empty()) { - *error = CreateErrorFromVector("Message size parser", &error_list); + *error = ServiceConfig::CreateErrorFromVector("Message size parser", + &error_list); return nullptr; } return UniquePtr(New( From b9a279c030df023f3ca8979d45708add4d7b0717 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 22 Apr 2019 23:53:53 +0200 Subject: [PATCH 035/112] Resolving ambiguous call to CreateCustomChannel. --- test/cpp/client/client_channel_stress_test.cc | 2 +- test/cpp/end2end/async_end2end_test.cc | 4 ++-- test/cpp/end2end/channelz_service_test.cc | 6 +++--- test/cpp/end2end/client_callback_end2end_test.cc | 4 ++-- test/cpp/end2end/client_lb_end2end_test.cc | 2 +- test/cpp/end2end/end2end_test.cc | 2 +- test/cpp/end2end/grpclb_end2end_test.cc | 2 +- test/cpp/end2end/shutdown_test.cc | 2 +- test/cpp/end2end/xds_end2end_test.cc | 2 +- test/cpp/microbenchmarks/fullstack_fixtures.h | 2 +- test/cpp/util/create_test_channel.cc | 8 ++++---- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 91419cb257b..195308c39b0 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -268,7 +268,7 @@ class ClientChannelStressTest { std::ostringstream uri; uri << "fake:///servername_not_used"; channel_ = - CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index e09f54dcc3f..f8e65ecff41 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -295,7 +295,7 @@ class AsyncEnd2endTest : public ::testing::TestWithParam { GetParam().credentials_type, &args); std::shared_ptr channel = !(GetParam().inproc) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) : server_->InProcessChannel(args); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -1256,7 +1256,7 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { GetParam().credentials_type, &args); std::shared_ptr channel = !(GetParam().inproc) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc index fe52a64db48..26ef59fbeb3 100644 --- a/test/cpp/end2end/channelz_service_test.cc +++ b/test/cpp/end2end/channelz_service_test.cc @@ -145,7 +145,7 @@ class ChannelzServerTest : public ::testing::Test { ChannelArguments args; args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1); args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE, 1024); - std::shared_ptr channel_to_backend = CreateCustomChannel( + std::shared_ptr channel_to_backend = ::grpc::CreateCustomChannel( backend_server_address, InsecureChannelCredentials(), args); proxy_service_.AddChannelToBackend(channel_to_backend); } @@ -157,7 +157,7 @@ class ChannelzServerTest : public ::testing::Test { // disable channelz. We only want to focus on proxy to backend outbound. args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0); std::shared_ptr channel = - CreateCustomChannel(target, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel); echo_stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -171,7 +171,7 @@ class ChannelzServerTest : public ::testing::Test { // This ensures that gRPC will not do connection sharing. args.SetInt("salt", salt++); std::shared_ptr channel = - CreateCustomChannel(target, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(target, InsecureChannelCredentials(), args); return grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index 821fcc2da6d..cb1d734c800 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -143,7 +143,7 @@ class ClientCallbackEnd2endTest case Protocol::TCP: if (!GetParam().use_interceptors) { channel_ = - CreateCustomChannel(server_address_.str(), channel_creds, args); + ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, @@ -1094,7 +1094,7 @@ TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { GetParam().credentials_type, &args); std::shared_ptr channel = (GetParam().protocol == Protocol::TCP) - ? CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 77f9db94acc..b6c4ad7bd2d 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -236,7 +236,7 @@ class ClientLbEnd2endTest : public ::testing::Test { } // else, default to pick first args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); - return CreateCustomChannel("fake:///", creds_, args); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); } bool SendRpc( diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 40023c72f62..0b4df97f4cb 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -341,7 +341,7 @@ class End2endTest : public ::testing::TestWithParam { if (!GetParam().inproc) { if (!GetParam().use_interceptors) { channel_ = - CreateCustomChannel(server_address_.str(), channel_creds, args); + ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index ee8b3e1e52b..7477878faa0 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -433,7 +433,7 @@ class GrpclbEnd2endTest : public ::testing::Test { channel_creds, call_creds, nullptr))); call_creds->Unref(); channel_creds->Unref(); - channel_ = CreateCustomChannel(uri.str(), creds, args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index da42178d67c..9e925364b1f 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -86,7 +86,7 @@ class ShutdownTest : public ::testing::TestWithParam { ChannelArguments args; auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args); - channel_ = CreateCustomChannel(target, channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(target, channel_creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 11a64264494..04bec5a9ee8 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -432,7 +432,7 @@ class XdsEnd2endTest : public ::testing::Test { channel_creds, call_creds, nullptr))); call_creds->Unref(); channel_creds->Unref(); - channel_ = CreateCustomChannel(uri.str(), creds, args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 6bbf553bbd8..ed231752438 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -87,7 +87,7 @@ class FullstackFixture : public BaseFixture { config.ApplyCommonChannelArguments(&args); if (address.length() > 0) { channel_ = - CreateCustomChannel(address, InsecureChannelCredentials(), args); + ::grpc::CreateCustomChannel(address, InsecureChannelCredentials(), args); } else { channel_ = server_->InProcessChannel(args); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index 79a5e13d993..d036e785360 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -118,7 +118,7 @@ std::shared_ptr CreateTestChannel( if (creds.get()) { channel_creds = CompositeChannelCredentials(channel_creds, creds); } - return CreateCustomChannel(server, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); } std::shared_ptr CreateTestChannel( @@ -132,7 +132,7 @@ std::shared_ptr CreateTestChannel( std::shared_ptr channel_creds; if (cred_type.empty()) { if (interceptor_creators.empty()) { - return CreateCustomChannel(server, InsecureChannelCredentials(), args); + return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), args); } else { return experimental::CreateCustomChannelWithInterceptors( server, InsecureChannelCredentials(), args, @@ -159,7 +159,7 @@ std::shared_ptr CreateTestChannel( channel_creds = CompositeChannelCredentials(channel_creds, creds); } if (interceptor_creators.empty()) { - return CreateCustomChannel(connect_to, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(connect_to, channel_creds, channel_args); } else { return experimental::CreateCustomChannelWithInterceptors( connect_to, channel_creds, channel_args, @@ -171,7 +171,7 @@ std::shared_ptr CreateTestChannel( GPR_ASSERT(channel_creds != nullptr); if (interceptor_creators.empty()) { - return CreateCustomChannel(server, channel_creds, args); + return ::grpc::CreateCustomChannel(server, channel_creds, args); } else { return experimental::CreateCustomChannelWithInterceptors( server, channel_creds, args, std::move(interceptor_creators)); From abcdf2d1832544f3e11775997ad847051a6f3809 Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Mon, 22 Apr 2019 16:32:26 -0600 Subject: [PATCH 036/112] Party like its 2015 --- src/ruby/spec/errors_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb index 30e897700b3..9d64277290a 100644 --- a/src/ruby/spec/errors_spec.rb +++ b/src/ruby/spec/errors_spec.rb @@ -1,13 +1,13 @@ -# Copyright 2019 gRPC authors. +# Copyright 2015 gRPC authors. # -# Licensed under the Apache License, Version 2.0 (the 'License'); +# Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, +# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. From 5f30da6dd128a311c92fc4b8df762caff8c4e11b Mon Sep 17 00:00:00 2001 From: Mike Moore Date: Mon, 22 Apr 2019 16:35:07 -0600 Subject: [PATCH 037/112] Update variable names in spec --- src/ruby/spec/errors_spec.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ruby/spec/errors_spec.rb b/src/ruby/spec/errors_spec.rb index 9d64277290a..bf27a537405 100644 --- a/src/ruby/spec/errors_spec.rb +++ b/src/ruby/spec/errors_spec.rb @@ -128,13 +128,14 @@ describe GRPC::BadStatus do expect(exception.to_rpc_status).to be nil + error_msg = 'parse error: to_rpc_status failed' + error_desc = ' ' \ + 'Error occurred during parsing: Invalid wire type' + # Check that the parse error was logged correctly log_contents = @log_output.read - expected_line_1 = 'WARN GRPC : parse error: to_rpc_status failed' - expected_line_2 = 'WARN GRPC : ' \ - 'Error occurred during parsing: Invalid wire type' - expect(log_contents).to include expected_line_1 - expect(log_contents).to include expected_line_2 + expect(log_contents).to include "WARN GRPC : #{error_msg}" + expect(log_contents).to include "WARN GRPC : #{error_desc}" end end end From dc1bcf876225f93da86ea5916133e868c95adc3a Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 22 Apr 2019 17:31:55 -0700 Subject: [PATCH 038/112] Consolidate helper function from windows and libuv --- BUILD | 2 + BUILD.gn | 2 + CMakeLists.txt | 2 + Makefile | 2 + build.yaml | 2 + config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 1 + gRPC-Core.podspec | 3 + grpc.gemspec | 2 + grpc.gyp | 2 + package.xml | 2 + .../dns/c_ares/grpc_ares_wrapper_libuv.cc | 53 +----------- .../c_ares/grpc_ares_wrapper_libuv_windows.cc | 83 +++++++++++++++++++ .../c_ares/grpc_ares_wrapper_libuv_windows.h | 14 ++++ .../dns/c_ares/grpc_ares_wrapper_windows.cc | 50 ----------- src/python/grpcio/grpc_core_dependencies.py | 1 + tools/doxygen/Doxyfile.core.internal | 2 + .../generated/sources_and_headers.json | 5 +- 19 files changed, 127 insertions(+), 103 deletions(-) create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc create mode 100644 src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h diff --git a/BUILD b/BUILD index 58f0855961e..69ca8fb2adc 100644 --- a/BUILD +++ b/BUILD @@ -1558,12 +1558,14 @@ grpc_cc_library( "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", ], hdrs = [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", ], external_deps = [ "cares", diff --git a/BUILD.gn b/BUILD.gn index a188ed86ac3..4210d5f1f0c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -316,6 +316,8 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc", "src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index dd32088e97f..9cbaf34f737 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1287,6 +1287,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc @@ -2658,6 +2659,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc diff --git a/Makefile b/Makefile index b1dcc82c601..300e8d5890a 100644 --- a/Makefile +++ b/Makefile @@ -3742,6 +3742,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ @@ -5061,6 +5062,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ diff --git a/build.yaml b/build.yaml index 48c45eb799d..d470c0a7eb5 100644 --- a/build.yaml +++ b/build.yaml @@ -778,6 +778,7 @@ filegroups: headers: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h src: - src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc @@ -787,6 +788,7 @@ filegroups: - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc + - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc plugin: grpc_resolver_dns_ares diff --git a/config.m4 b/config.m4 index e255602a48d..93d90685f32 100644 --- a/config.m4 +++ b/config.m4 @@ -402,6 +402,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ + src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ diff --git a/config.w32 b/config.w32 index e83b3e3dd7f..352d1c446c8 100644 --- a/config.w32 +++ b/config.w32 @@ -377,6 +377,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_libuv_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index b8f3f56a83f..29a7c411a42 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -545,6 +545,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4a2ea853f29..5ca70a533da 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -528,6 +528,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', @@ -849,6 +850,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -1170,6 +1172,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h', 'src/core/ext/filters/max_age/max_age_filter.h', 'src/core/ext/filters/message_size/message_size_filter.h', 'src/core/ext/filters/http/client_authority_filter.h', diff --git a/grpc.gemspec b/grpc.gemspec index b7e0d54eaab..31119577251 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -462,6 +462,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.h ) s.files += %w( src/core/ext/filters/message_size/message_size_filter.h ) s.files += %w( src/core/ext/filters/http/client_authority_filter.h ) @@ -786,6 +787,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) diff --git a/grpc.gyp b/grpc.gyp index 19427da3ca6..351d50411b7 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -584,6 +584,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', @@ -1325,6 +1326,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', diff --git a/package.xml b/package.xml index 26cc17756e8..c8ac7a47966 100644 --- a/package.xml +++ b/package.xml @@ -467,6 +467,7 @@ + @@ -791,6 +792,7 @@ + diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc index 08f3d9ce30d..cab74f8ba64 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc @@ -25,6 +25,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" @@ -36,58 +37,6 @@ bool grpc_ares_query_ipv6() { return true; } -/* The following two functions were copied entirely from the Windows file. This - * code can run on Windows so it can have the same problem. */ -static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); - return true; - } - return false; -} - bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc new file mode 100644 index 00000000000..837593a62bc --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -0,0 +1,83 @@ +/* + * + * Copyright 2016 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/iomgr/port.h" +#if GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) + +#include + +#include "src/core/ext/filters/client_channel/parse_address.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port) { + gpr_split_host_port(name, host, port); + if (*host == nullptr) { + gpr_log(GPR_ERROR, + "Failed to parse %s into host:port during Windows localhost " + "resolution check.", + name); + return false; + } + if (*port == nullptr) { + if (default_port == nullptr) { + gpr_log(GPR_ERROR, + "No port or default port for %s during Windows localhost " + "resolution check.", + name); + return false; + } + *port = gpr_strdup(default_port); + } + if (gpr_stricmp(*host, "localhost") == 0) { + GPR_ASSERT(*addrs == nullptr); + *addrs = grpc_core::MakeUnique(); + uint16_t numeric_port = grpc_strhtons(*port); + // Append the ipv6 loopback address. + struct sockaddr_in6 ipv6_loopback_addr; + memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); + ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; + ipv6_loopback_addr.sin6_family = AF_INET6; + ipv6_loopback_addr.sin6_port = numeric_port; + (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), + nullptr /* args */); + // Append the ipv4 loopback address. + struct sockaddr_in ipv4_loopback_addr; + memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); + ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; + ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; + ipv4_loopback_addr.sin_family = AF_INET; + ipv4_loopback_addr.sin_port = numeric_port; + (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), + nullptr /* args */); + // Let the address sorter figure out which one should be tried first. + grpc_cares_wrapper_address_sorting_sort(addrs->get()); + return true; + } + return false; +} + +#endif /* GRPC_ARES == 1 && (defined(GRPC_UV) || defined(GPR_WINDOWS)) */ \ No newline at end of file diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h new file mode 100644 index 00000000000..07c0e37552b --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h @@ -0,0 +1,14 @@ +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H + +#include + +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" + +bool inner_maybe_resolve_localhost_manually_locked( + const char* name, const char* default_port, + grpc_core::UniquePtr* addrs, char** host, + char** port); + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H \ + */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index 202452f1b2b..f3adc417793 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -32,56 +32,6 @@ bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); } -static bool inner_maybe_resolve_localhost_manually_locked( - const char* name, const char* default_port, - grpc_core::UniquePtr* addrs, char** host, - char** port) { - gpr_split_host_port(name, host, port); - if (*host == nullptr) { - gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " - "resolution check.", - name); - return false; - } - if (*port == nullptr) { - if (default_port == nullptr) { - gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " - "resolution check.", - name); - return false; - } - *port = gpr_strdup(default_port); - } - if (gpr_stricmp(*host, "localhost") == 0) { - GPR_ASSERT(*addrs == nullptr); - *addrs = grpc_core::MakeUnique(); - uint16_t numeric_port = grpc_strhtons(*port); - // Append the ipv6 loopback address. - struct sockaddr_in6 ipv6_loopback_addr; - memset(&ipv6_loopback_addr, 0, sizeof(ipv6_loopback_addr)); - ((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1; - ipv6_loopback_addr.sin6_family = AF_INET6; - ipv6_loopback_addr.sin6_port = numeric_port; - (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr), - nullptr /* args */); - // Append the ipv4 loopback address. - struct sockaddr_in ipv4_loopback_addr; - memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr)); - ((char*)&ipv4_loopback_addr.sin_addr)[0] = 0x7f; - ((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01; - ipv4_loopback_addr.sin_family = AF_INET; - ipv4_loopback_addr.sin_port = numeric_port; - (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr), - nullptr /* args */); - // Let the address sorter figure out which one should be tried first. - grpc_cares_wrapper_address_sorting_sort(addrs->get()); - return true; - } - return false; -} - bool grpc_ares_maybe_resolve_localhost_manually_locked( const char* name, const char* default_port, grpc_core::UniquePtr* addrs) { diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 9c375f5eb87..7f0a9ebc72e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -376,6 +376,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc', + 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index a3869cd239c..4f13d987a6f 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -949,6 +949,8 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc \ +src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \ src/core/ext/filters/client_channel/resolver/dns/native/README.md \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 52c69ad10b5..11b5e3ea4af 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -9075,7 +9075,8 @@ ], "headers": [ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h", - "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" ], "is_filegroup": true, "language": "c", @@ -9091,6 +9092,8 @@ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc", + "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc", "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" ], From 70839d966f1c481eadc7d27ac06bb1426bbde989 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 22 Apr 2019 19:12:11 -0700 Subject: [PATCH 039/112] Reviewer comments --- .../filters/client_channel/client_channel.cc | 28 +-- .../client_channel/client_channel_plugin.cc | 1 - .../ext/filters/client_channel/lb_policy.cc | 59 ------- .../ext/filters/client_channel/lb_policy.h | 18 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 8 +- .../lb_policy/pick_first/pick_first.cc | 5 +- .../lb_policy/round_robin/round_robin.cc | 5 +- .../client_channel/lb_policy/xds/xds.cc | 15 +- .../client_channel/lb_policy_factory.h | 9 - .../client_channel/lb_policy_registry.cc | 91 +++++++++- .../client_channel/lb_policy_registry.h | 8 +- .../client_channel/resolver_result_parsing.cc | 102 +++++------ .../client_channel/resolver_result_parsing.h | 19 +- .../client_channel/resolving_lb_policy.cc | 2 +- .../client_channel/resolving_lb_policy.h | 3 +- .../filters/client_channel/service_config.h | 162 ------------------ .../ext/filters/client_channel/subchannel.cc | 1 - .../message_size/message_size_filter.cc | 3 +- .../client_channel/service_config_test.cc | 13 +- 19 files changed, 214 insertions(+), 338 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 15fe9a8c70a..901655bd3df 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -223,7 +223,7 @@ class ChannelData { ~ChannelData(); static bool ProcessResolverResultLocked( - void* arg, Resolver::Result* result, const char** lb_policy_name, + void* arg, const Resolver::Result& result, const char** lb_policy_name, const ParsedLoadBalancingConfig** lb_policy_config, const HealthCheckParsedObject** health_check); @@ -252,8 +252,8 @@ class ChannelData { QueuedPick* queued_picks_ = nullptr; // Linked list of queued picks. // Data from service config. bool received_service_config_data_ = false; - grpc_core::RefCountedPtr retry_throttle_data_; - grpc_core::RefCountedPtr service_config_; + RefCountedPtr retry_throttle_data_; + RefCountedPtr service_config_; // // Fields used in the control plane. Guarded by combiner. @@ -619,7 +619,7 @@ class CallData { grpc_call_context_element* call_context_; RefCountedPtr retry_throttle_data_; - RefCountedPtr service_config_; + RefCountedPtr service_config_; const ClientChannelMethodParsedObject* method_params_ = nullptr; RefCountedPtr subchannel_call_; @@ -1110,11 +1110,11 @@ ChannelData::~ChannelData() { // Synchronous callback from ResolvingLoadBalancingPolicy to process a // resolver result update. bool ChannelData::ProcessResolverResultLocked( - void* arg, Resolver::Result* result, const char** lb_policy_name, + void* arg, const Resolver::Result& result, const char** lb_policy_name, const ParsedLoadBalancingConfig** lb_policy_config, - const grpc_core::HealthCheckParsedObject** health_check) { + const HealthCheckParsedObject** health_check) { ChannelData* chand = static_cast(arg); - ProcessedResolverResult resolver_result(result, chand->enable_retries_); + ProcessedResolverResult resolver_result(result); const char* service_config_json = resolver_result.service_config_json(); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", @@ -1854,7 +1854,7 @@ void CallData::DoRetry(grpc_call_element* elem, // Compute backoff delay. grpc_millis next_attempt_time; if (server_pushback_ms >= 0) { - next_attempt_time = grpc_core::ExecCtx::Get()->Now() + server_pushback_ms; + next_attempt_time = ExecCtx::Get()->Now() + server_pushback_ms; last_attempt_got_server_pushback_ = true; } else { if (num_attempts_completed_ == 1 || last_attempt_got_server_pushback_) { @@ -1871,7 +1871,7 @@ void CallData::DoRetry(grpc_call_element* elem, if (grpc_client_channel_call_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p calld=%p: retrying failed call in %" PRId64 " ms", chand, - this, next_attempt_time - grpc_core::ExecCtx::Get()->Now()); + this, next_attempt_time - ExecCtx::Get()->Now()); } // Schedule retry after computed delay. GRPC_CLOSURE_INIT(&pick_closure_, StartPickLocked, elem, @@ -3079,22 +3079,22 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, this); } - if (chand->service_config() != nullptr) { + service_config_ = chand->service_config(); + if (service_config_ != nullptr) { // Store a ref to the service_config in CallData. Also, save pointers to the // ServiceConfig and ServiceConfigObjectsVector (for this call) in the // call_context so that all future filters can access it. - service_config_ = chand->service_config(); call_context_[GRPC_SERVICE_CONFIG].value = &service_config_; const auto* method_params_vector_ptr = - chand->service_config()->GetMethodServiceConfigObjectsVector(path_); + service_config_->GetMethodServiceConfigObjectsVector(path_); if (method_params_vector_ptr != nullptr) { method_params_ = static_cast( ((*method_params_vector_ptr) - [grpc_core::internal::ClientChannelServiceConfigParser:: + [internal::ClientChannelServiceConfigParser:: client_channel_service_config_parser_index()]) .get()); call_context_[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value = - const_cast( + const_cast( method_params_vector_ptr); } } diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 729043bebfc..a5d2c83ecd3 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -53,7 +53,6 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { void grpc_service_config_register_parsers() { grpc_core::internal::ClientChannelServiceConfigParser::Register(); - grpc_core::MessageSizeParser::Register(); grpc_core::HealthCheckParser::Register(); } diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 19142e3f3b7..90ac4d786ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -62,65 +62,6 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, policy->Unref(); } -grpc_json* LoadBalancingPolicy::ParseLoadBalancingConfig( - const grpc_json* lb_config_array, const char* field_name, - grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - char* error_msg; - if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { - gpr_asprintf(&error_msg, "field:%s error:type should be array", field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } - // Find the first LB policy that this client supports. - for (const grpc_json* lb_config = lb_config_array->child; - lb_config != nullptr; lb_config = lb_config->next) { - if (lb_config->type != GRPC_JSON_OBJECT) { - gpr_asprintf(&error_msg, - "field:%s error:child entry should be of type object", - field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } - grpc_json* policy = nullptr; - for (grpc_json* field = lb_config->child; field != nullptr; - field = field->next) { - if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) { - gpr_asprintf(&error_msg, - "field:%s error:child entry should be of type object", - field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } - if (policy != nullptr) { - gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } // Violate "oneof" type. - policy = field; - } - if (policy == nullptr) { - gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", - field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; - } - // If we support this policy, then select it. - if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { - return policy; - } - } - gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); - *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); - gpr_free(error_msg); - return nullptr; -} - // // LoadBalancingPolicy::UpdateArgs // diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 2ef968a616a..057222aa14a 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -36,7 +36,17 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount; namespace grpc_core { -class ParsedLoadBalancingConfig; +/// Interface for parsed forms of load balancing configs found in a service +/// config. +class ParsedLoadBalancingConfig { + public: + virtual ~ParsedLoadBalancingConfig() = default; + + // Returns the load balancing policy name + virtual const char* name() const GRPC_ABSTRACT; + + GRPC_ABSTRACT_BASE_CLASS; +}; /// Interface for load balancing policies. /// @@ -272,12 +282,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { void Orphan() override; - /// Returns the JSON node of policy (with both policy name and config content) - /// given the JSON node of a LoadBalancingConfig array. - static grpc_json* ParseLoadBalancingConfig(const grpc_json* lb_config_array, - const char* field_name, - grpc_error** error); - // A picker that returns PICK_QUEUE for all picks. // Also calls the parent LB policy's ExitIdleLocked() method when the // first pick is seen. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index d8e942e6570..98c9f81ddda 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1814,8 +1814,10 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - GPR_DEBUG_ASSERT(json != nullptr); - GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + if (json == nullptr) { + return UniquePtr( + New(nullptr)); + } InlinedVector error_list; UniquePtr child_policy = nullptr; @@ -1830,7 +1832,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "childPolicy", &parse_error); + field, &parse_error); if (parse_error != GRPC_ERROR_NONE) { error_list.push_back(parse_error); } diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 21fda23ab71..899c6f14b6c 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -548,8 +548,9 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { - GPR_DEBUG_ASSERT(json != nullptr); - GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + if (json != nullptr) { + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + } return UniquePtr(New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 193e383a433..76187d0978a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -525,8 +525,9 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { - GPR_DEBUG_ASSERT(json != nullptr); - GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + if (json != nullptr) { + GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); + } return UniquePtr(New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 7b9c2b320fd..2a00543f593 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1667,7 +1667,16 @@ class XdsFactory : public LoadBalancingPolicyFactory { UniquePtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { - GPR_DEBUG_ASSERT(json != nullptr); + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + if (json == nullptr) { + // xds was mentioned as a policy in the deprecated loadBalancingPolicy + // field. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Xds Parser has required field - " + "balancerName. Please use loadBalancingConfig instead of the " + "deprecated loadBalancingPolicy"); + return nullptr; + } GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); InlinedVector error_list; @@ -1697,7 +1706,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "childPolicy", &parse_error); + field, &parse_error); if (child_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); @@ -1710,7 +1719,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "fallbackPolicy", &parse_error); + field, &parse_error); if (fallback_policy == nullptr) { GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE); error_list.push_back(parse_error); diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index cb7b547f589..4aee5848c86 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -27,15 +27,6 @@ namespace grpc_core { -class ParsedLoadBalancingConfig { - public: - virtual ~ParsedLoadBalancingConfig() = default; - - virtual const char* name() const GRPC_ABSTRACT; - - GRPC_ABSTRACT_BASE_CLASS; -}; - class LoadBalancingPolicyFactory { public: /// Returns a new LB policy instance. diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index f4cc115eefc..78b8a6f706f 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -99,25 +99,87 @@ bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; } +namespace { +// Returns the JSON node of policy (with both policy name and config content) +// given the JSON node of a LoadBalancingConfig array. +grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, + grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + char* error_msg; + if (lb_config_array == nullptr || lb_config_array->type != GRPC_JSON_ARRAY) { + gpr_asprintf(&error_msg, "field:%s error:type should be array", + lb_config_array->key); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + const char* field_name = lb_config_array->key; + // Find the first LB policy that this client supports. + for (const grpc_json* lb_config = lb_config_array->child; + lb_config != nullptr; lb_config = lb_config->next) { + if (lb_config->type != GRPC_JSON_OBJECT) { + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + grpc_json* policy = nullptr; + for (grpc_json* field = lb_config->child; field != nullptr; + field = field->next) { + if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) { + gpr_asprintf(&error_msg, + "field:%s error:child entry should be of type object", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + if (policy != nullptr) { + gpr_asprintf(&error_msg, "field:%s error:oneOf violation", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } // Violate "oneof" type. + policy = field; + } + if (policy == nullptr) { + gpr_asprintf(&error_msg, "field:%s error:no policy found in child entry", + field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; + } + // If we support this policy, then select it. + if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { + return policy; + } + } + gpr_asprintf(&error_msg, "field:%s error:No known policy", field_name); + *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg); + gpr_free(error_msg); + return nullptr; +} +} // namespace + UniquePtr LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, - const char* field_name, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); GPR_ASSERT(g_state != nullptr); - const grpc_json* policy = - LoadBalancingPolicy::ParseLoadBalancingConfig(json, field_name, error); + const grpc_json* policy = ParseLoadBalancingConfigHelper(json, error); if (policy == nullptr) { return nullptr; } else { - GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE); + GPR_DEBUG_ASSERT(*error == GRPC_ERROR_NONE && json != nullptr); // Find factory. LoadBalancingPolicyFactory* factory = g_state->GetLoadBalancingPolicyFactory(policy->key); if (factory == nullptr) { char* msg; gpr_asprintf(&msg, "field:%s error:Factory not found to create policy", - field_name); + json->key); *error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); gpr_free(msg); return nullptr; @@ -127,4 +189,23 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, } } +grpc_error* LoadBalancingPolicyRegistry::ParseDeprecatedLoadBalancingPolicy( + const grpc_json* json) { + GPR_DEBUG_ASSERT(g_state != nullptr); + GPR_DEBUG_ASSERT(json != nullptr); + if (json->type != GRPC_JSON_STRING) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:type should be string"); + } + auto* factory = g_state->GetLoadBalancingPolicyFactory(json->value); + if (factory == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:loadBalancingPolicy error:Unknown lb policy"); + } + grpc_error* error = GRPC_ERROR_NONE; + // Check if the load balancing policy allows an empty config + factory->ParseLoadBalancingConfig(nullptr, &error); + return error; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 8ac845c59f1..ffeb44de9de 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -52,8 +52,14 @@ class LoadBalancingPolicyRegistry { /// registry. static bool LoadBalancingPolicyExists(const char* name); + /// Returns a parsed object of the load balancing policy to be used from a + /// LoadBalancingConfig array \a json. \a field_name specifies static UniquePtr ParseLoadBalancingConfig( - const grpc_json* json, const char* field_name, grpc_error** error); + const grpc_json* json, grpc_error** error); + + /// Validates if the deprecated loadBalancingPolicy field can be parsed. + /// Returns GRPC_ERROR_NONE if successfully parsed. + static grpc_error* ParseDeprecatedLoadBalancingPolicy(const grpc_json* json); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index dea8c915856..2d5a5bb8e2d 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -59,13 +59,13 @@ void ClientChannelServiceConfigParser::Register() { } ProcessedResolverResult::ProcessedResolverResult( - Resolver::Result* resolver_result, bool parse_retry) - : service_config_(resolver_result->service_config) { + const Resolver::Result& resolver_result) + : service_config_(resolver_result.service_config) { // If resolver did not return a service config, use the default // specified via the client API. if (service_config_ == nullptr) { const char* service_config_json = grpc_channel_arg_get_string( - grpc_channel_args_find(resolver_result->args, GRPC_ARG_SERVICE_CONFIG)); + grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVICE_CONFIG)); if (service_config_json != nullptr) { grpc_error* error = GRPC_ERROR_NONE; service_config_ = ServiceConfig::Create(service_config_json, &error); @@ -74,60 +74,62 @@ ProcessedResolverResult::ProcessedResolverResult( } } // Process service config. - ProcessServiceConfig(*resolver_result, parse_retry); - // If no LB config was found above, just find the LB policy name then. - if (lb_policy_name_ == nullptr) ProcessLbPolicyName(*resolver_result); + ProcessServiceConfig(resolver_result); + ProcessLbPolicy(resolver_result); } void ProcessedResolverResult::ProcessServiceConfig( - const Resolver::Result& resolver_result, bool parse_retry) { + const Resolver::Result& resolver_result) { if (service_config_ == nullptr) return; health_check_ = static_cast( service_config_->GetParsedGlobalServiceConfigObject( HealthCheckParser::ParserIndex())); service_config_json_ = service_config_->service_config_json(); - auto* parsed_object = static_cast( + auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( ClientChannelServiceConfigParser:: client_channel_service_config_parser_index())); - if (!parsed_object) { return; } - if (parse_retry) { - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); - const char* server_uri = grpc_channel_arg_get_string(channel_arg); - GPR_ASSERT(server_uri != nullptr); - grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); - server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; - if (parsed_object->retry_throttling().has_value()) { - retry_throttle_data_ = - grpc_core::internal::ServerRetryThrottleMap::GetDataForServer( - server_name_, - parsed_object->retry_throttling().value().max_milli_tokens, - parsed_object->retry_throttling().value().milli_token_ratio); - } - grpc_uri_destroy(uri); - } - if (parsed_object->parsed_lb_config()) { - lb_policy_name_.reset( - gpr_strdup(parsed_object->parsed_lb_config()->name())); - lb_policy_config_ = parsed_object->parsed_lb_config(); - } else { - lb_policy_name_.reset( - gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); + const char* server_uri = grpc_channel_arg_get_string(channel_arg); + GPR_ASSERT(server_uri != nullptr); + grpc_uri* uri = grpc_uri_parse(server_uri, true); + GPR_ASSERT(uri->path[0] != '\0'); + if (parsed_object->retry_throttling().has_value()) { + char* server_name = uri->path[0] == '/' ? uri->path + 1 : uri->path; + retry_throttle_data_ = internal::ServerRetryThrottleMap::GetDataForServer( + server_name, parsed_object->retry_throttling().value().max_milli_tokens, + parsed_object->retry_throttling().value().milli_token_ratio); } + grpc_uri_destroy(uri); } -void ProcessedResolverResult::ProcessLbPolicyName( +void ProcessedResolverResult::ProcessLbPolicy( const Resolver::Result& resolver_result) { // Prefer the LB policy name found in the service config. - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); + if (service_config_ != nullptr) { + auto* parsed_object = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + ClientChannelServiceConfigParser:: + client_channel_service_config_parser_index())); + if (parsed_object != nullptr) { + if (parsed_object->parsed_lb_config()) { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); + lb_policy_config_ = parsed_object->parsed_lb_config(); + } else { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + if (lb_policy_name_ != nullptr) { + char* lb_policy_name = lb_policy_name_.get(); + for (size_t i = 0; i < strlen(lb_policy_name); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); + } + } + } } } // Otherwise, find the LB policy name set by the client API. @@ -342,8 +344,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, InlinedVector error_list; UniquePtr parsed_lb_config; const char* lb_policy_name = nullptr; - grpc_core::Optional - retry_throttling; + Optional retry_throttling; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) { continue; // Not the LB config global parameter @@ -356,8 +357,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } else { grpc_error* parse_error = GRPC_ERROR_NONE; parsed_lb_config = - LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( - field, "loadBalancingConfig", &parse_error); + LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, + &parse_error); if (parsed_lb_config == nullptr) { error_list.push_back(parse_error); } @@ -375,12 +376,15 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, field->value)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); - } else if (strcmp(field->value, "xds_experimental") == 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:xds not supported with this " - "field. Please use loadBalancingConfig")); } else { - lb_policy_name = field->value; + grpc_error* parsing_error = + LoadBalancingPolicyRegistry::ParseDeprecatedLoadBalancingPolicy( + field); + if (parsing_error != GRPC_ERROR_NONE) { + error_list.push_back(parsing_error); + } else { + lb_policy_name = field->value; + } } } // Parse retry throttling @@ -392,8 +396,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling error:Duplicate entry")); } else { - grpc_core::Optional max_milli_tokens(false, 0); - grpc_core::Optional milli_token_ratio(false, 0); + Optional max_milli_tokens(false, 0); + Optional milli_token_ratio(false, 0); for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 327818f668d..02a49bad2e9 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -47,12 +47,12 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { ClientChannelGlobalParsedObject( UniquePtr parsed_lb_config, const char* parsed_deprecated_lb_policy, - const grpc_core::Optional& retry_throttling) + const Optional& retry_throttling) : parsed_lb_config_(std::move(parsed_lb_config)), parsed_deprecated_lb_policy_(parsed_deprecated_lb_policy), retry_throttling_(retry_throttling) {} - grpc_core::Optional retry_throttling() const { + Optional retry_throttling() const { return retry_throttling_; } @@ -67,7 +67,7 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { private: UniquePtr parsed_lb_config_; const char* parsed_deprecated_lb_policy_ = nullptr; - grpc_core::Optional retry_throttling_; + Optional retry_throttling_; }; class ClientChannelMethodParsedObject : public ServiceConfigParsedObject { @@ -116,9 +116,8 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser { class ProcessedResolverResult { public: // Processes the resolver result and populates the relative members - // for later consumption. Tries to parse retry parameters only if parse_retry - // is true. - ProcessedResolverResult(Resolver::Result* resolver_result, bool parse_retry); + // for later consumption. + ProcessedResolverResult(const Resolver::Result& resolver_result); // Getters. Any managed object's ownership is transferred. const char* service_config_json() { return service_config_json_; } @@ -137,11 +136,10 @@ class ProcessedResolverResult { private: // Finds the service config; extracts LB config and (maybe) retry throttle // params from it. - void ProcessServiceConfig(const Resolver::Result& resolver_result, - bool parse_retry); + void ProcessServiceConfig(const Resolver::Result& resolver_result); - // Finds the LB policy name (when no LB config was found). - void ProcessLbPolicyName(const Resolver::Result& resolver_result); + // Extracts the LB policy. + void ProcessLbPolicy(const Resolver::Result& resolver_result); // Parses the service config. Intended to be used by // ServiceConfig::ParseGlobalParams. @@ -159,7 +157,6 @@ class ProcessedResolverResult { UniquePtr lb_policy_name_; const ParsedLoadBalancingConfig* lb_policy_config_ = nullptr; // Retry throttle data. - char* server_name_ = nullptr; RefCountedPtr retry_throttle_data_; const HealthCheckParsedObject* health_check_ = nullptr; }; diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 29e87e8aefd..97f5e5fda80 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -539,7 +539,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( bool service_config_changed = false; if (process_resolver_result_ != nullptr) { service_config_changed = process_resolver_result_( - process_resolver_result_user_data_, &result, &lb_policy_name, + process_resolver_result_user_data_, result, &lb_policy_name, &lb_policy_config, &health_check); } else { lb_policy_name = child_policy_name_.get(); diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index afbee184690..84d134254d0 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -66,7 +66,8 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { // lb_policy_name and lb_policy_config to point to the right data. // Returns true if the service config has changed since the last result. typedef bool (*ProcessResolverResultCallback)( - void* user_data, Resolver::Result* result, const char** lb_policy_name, + void* user_data, const Resolver::Result& result, + const char** lb_policy_name, const ParsedLoadBalancingConfig** lb_policy_config, const HealthCheckParsedObject** health_check); // If error is set when this returns, then construction failed, and diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index f45cab9ee7d..0b7a8d33855 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -100,33 +100,6 @@ class ServiceConfig : public RefCounted { const char* service_config_json() const { return service_config_json_.get(); } - /// Invokes \a process_json() for each global parameter in the service - /// config. \a arg is passed as the second argument to \a process_json(). - template - using ProcessJson = void (*)(const grpc_json*, T*); - template - void ParseGlobalParams(ProcessJson process_json, T* arg) const; - - /// Creates a method config table based on the data in \a json. - /// The table's keys are request paths. The table's value type is - /// returned by \a create_value(), based on data parsed from the JSON tree. - /// Returns null on error. - template - using CreateValue = RefCountedPtr (*)(const grpc_json* method_config_json); - template - RefCountedPtr>> CreateMethodConfigTable( - CreateValue create_value) const; - - /// A helper function for looking up values in the table returned by - /// \a CreateMethodConfigTable(). - /// Gets the method config for the specified \a path, which should be of - /// the form "/service/method". - /// Returns null if the method has no config. - /// Caller does NOT own a reference to the result. - template - static RefCountedPtr MethodConfigTableLookup( - const SliceHashTable>& table, const grpc_slice& path); - /// Retrieves the parsed global service config object at index \a index. ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(size_t index) { GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); @@ -190,14 +163,6 @@ class ServiceConfig : public RefCounted { static UniquePtr ParseJsonMethodName(grpc_json* json, grpc_error** error); - // Parses the method config from \a json. Adds an entry to \a entries for - // each name found, incrementing \a idx for each entry added. - // Returns false on error. - template - static bool ParseJsonMethodConfig( - grpc_json* json, CreateValue create_value, - typename SliceHashTable>::Entry* entries, size_t* idx); - grpc_error* ParseJsonMethodConfigToServiceConfigObjectsTable( const grpc_json* json, SliceHashTable::Entry* entries, @@ -220,133 +185,6 @@ class ServiceConfig : public RefCounted { service_config_objects_vectors_storage_; }; -// -// implementation -- no user-serviceable parts below -// - -template -void ServiceConfig::ParseGlobalParams(ProcessJson process_json, - T* arg) const { - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return; - } - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return; - if (strcmp(field->key, "methodConfig") == 0) continue; - process_json(field, arg); - } -} - -template -bool ServiceConfig::ParseJsonMethodConfig( - grpc_json* json, CreateValue create_value, - typename SliceHashTable>::Entry* entries, size_t* idx) { - // Construct value. - RefCountedPtr method_config = create_value(json); - if (method_config == nullptr) return false; - // Construct list of paths. - InlinedVector, 10> paths; - for (grpc_json* child = json->child; child != nullptr; child = child->next) { - if (child->key == nullptr) continue; - if (strcmp(child->key, "name") == 0) { - if (child->type != GRPC_JSON_ARRAY) return false; - for (grpc_json* name = child->child; name != nullptr; name = name->next) { - grpc_error* error = GRPC_ERROR_NONE; - UniquePtr path = ParseJsonMethodName(name, &error); - // We are not reporting the error here. - GRPC_ERROR_UNREF(error); - if (path == nullptr) return false; - paths.push_back(std::move(path)); - } - } - } - if (paths.size() == 0) return false; // No names specified. - // Add entry for each path. - for (size_t i = 0; i < paths.size(); ++i) { - entries[*idx].key = grpc_slice_from_copied_string(paths[i].get()); - entries[*idx].value = method_config; // Takes a new ref. - ++*idx; - } - // Success. - return true; -} - -template -RefCountedPtr>> -ServiceConfig::CreateMethodConfigTable(CreateValue create_value) const { - // Traverse parsed JSON tree. - if (json_tree_->type != GRPC_JSON_OBJECT || json_tree_->key != nullptr) { - return nullptr; - } - size_t num_entries = 0; - typename SliceHashTable>::Entry* entries = nullptr; - for (grpc_json* field = json_tree_->child; field != nullptr; - field = field->next) { - if (field->key == nullptr) return nullptr; - if (strcmp(field->key, "methodConfig") == 0) { - if (entries != nullptr) return nullptr; // Duplicate. - if (field->type != GRPC_JSON_ARRAY) return nullptr; - // Find number of entries. - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - int count = CountNamesInMethodConfig(method); - if (count <= 0) return nullptr; - num_entries += static_cast(count); - } - // Populate method config table entries. - entries = static_cast>::Entry*>( - gpr_zalloc(num_entries * - sizeof(typename SliceHashTable>::Entry))); - size_t idx = 0; - for (grpc_json* method = field->child; method != nullptr; - method = method->next) { - if (!ParseJsonMethodConfig(method, create_value, entries, &idx)) { - for (size_t i = 0; i < idx; ++i) { - grpc_slice_unref_internal(entries[i].key); - entries[i].value.reset(); - } - gpr_free(entries); - return nullptr; - } - } - GPR_ASSERT(idx == num_entries); - } - } - // Instantiate method config table. - RefCountedPtr>> method_config_table; - if (entries != nullptr) { - method_config_table = - SliceHashTable>::Create(num_entries, entries, nullptr); - gpr_free(entries); - } - return method_config_table; -} - -template -RefCountedPtr ServiceConfig::MethodConfigTableLookup( - const SliceHashTable>& table, const grpc_slice& path) { - const RefCountedPtr* value = table.Get(path); - // If we didn't find a match for the path, try looking for a wildcard - // entry (i.e., change "/service/method" to "/service/*"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = (char*)gpr_malloc(len + 2); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = table.Get(wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - if (value == nullptr) return nullptr; - } - return RefCountedPtr(*value); -} - } // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVICE_CONFIG_H */ diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index ec2b01c65a8..b21fec7cc3f 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -565,7 +565,6 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - if (health_check != nullptr) { health_check_service_name_ = UniquePtr(gpr_strdup(health_check->service_name())); diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index f3976cb783f..d7bfa28fee1 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -291,7 +291,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, // Destructor for channel_data. static void destroy_channel_elem(grpc_channel_element* elem) { channel_data* chand = static_cast(elem->channel_data); - chand->svc_cfg.reset(); + chand->~channel_data(); } const grpc_channel_filter grpc_message_size_filter = { @@ -355,6 +355,7 @@ void grpc_message_size_filter_init(void) { grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, maybe_add_message_size_filter, nullptr); + grpc_core::MessageSizeParser::Register(); } void grpc_message_size_filter_shutdown(void) {} diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 7ea4a88e9bb..544d91ec02e 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -546,12 +546,13 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:" - "loadBalancingPolicy error:xds not supported)")); + std::regex e(std::string( + "(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:loadBalancingPolicy error:Xds " + "Parser has required field - balancerName. Please use " + "loadBalancingConfig instead of the deprecated loadBalancingPolicy)")); std::smatch match; std::string s(grpc_error_string(error)); EXPECT_TRUE(std::regex_search(s, match, e)); From 4309a98b66279a5393d2f69bccd6eed3397b8201 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Mon, 22 Apr 2019 21:18:47 -0700 Subject: [PATCH 040/112] Health checking service name to be passed as a channel arg for now --- .../filters/client_channel/client_channel.cc | 32 ++++++++++++------- .../client_channel/client_channel_factory.h | 5 ++- .../health/health_check_parser.cc | 1 + .../ext/filters/client_channel/lb_policy.cc | 6 ---- .../ext/filters/client_channel/lb_policy.h | 6 ++-- .../client_channel/lb_policy/grpclb/grpclb.cc | 11 ++----- .../lb_policy/pick_first/pick_first.cc | 8 ++--- .../lb_policy/round_robin/round_robin.cc | 8 ++--- .../lb_policy/subchannel_list.h | 7 ++-- .../client_channel/lb_policy/xds/xds.cc | 10 ++---- .../client_channel/resolving_lb_policy.cc | 20 ++++-------- .../client_channel/resolving_lb_policy.h | 6 ++-- .../ext/filters/client_channel/subchannel.cc | 15 ++++----- .../ext/filters/client_channel/subchannel.h | 6 ++-- .../chttp2/client/insecure/channel_create.cc | 6 ++-- .../client/secure/secure_channel_create.cc | 6 ++-- test/core/util/test_lb_policies.cc | 7 ++-- test/cpp/microbenchmarks/bm_call_create.cc | 3 +- 18 files changed, 64 insertions(+), 99 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 901655bd3df..ffb2b9a904b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -224,8 +224,7 @@ class ChannelData { static bool ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config, - const HealthCheckParsedObject** health_check); + const ParsedLoadBalancingConfig** lb_policy_config); grpc_error* DoPingLocked(grpc_transport_op* op); @@ -932,15 +931,26 @@ class ChannelData::ClientChannelControlHelper "ClientChannelControlHelper"); } - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override { - grpc_arg arg = SubchannelPoolInterface::CreateChannelArg( + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + grpc_arg args_to_add[2]; + int num_args_to_add = 0; + if (chand_->service_config_ != nullptr) { + /*const auto* health_check_object = static_cast( + chand_->service_config_->GetParsedGlobalServiceConfigObject( + HealthCheckParser::ParserIndex())); + if (health_check_object != nullptr) { + args_to_add[0] = grpc_channel_arg_string_create( + const_cast("grpc.temp.health_check"), + const_cast(health_check_object->service_name())); + num_args_to_add++; + }*/ + } + args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); grpc_channel_args* new_args = - grpc_channel_args_copy_and_add(&args, &arg, 1); - Subchannel* subchannel = chand_->client_channel_factory_->CreateSubchannel( - new_args, health_check); + grpc_channel_args_copy_and_add(&args, args_to_add, num_args_to_add); + Subchannel* subchannel = + chand_->client_channel_factory_->CreateSubchannel(new_args); grpc_channel_args_destroy(new_args); return subchannel; } @@ -1111,8 +1121,7 @@ ChannelData::~ChannelData() { // resolver result update. bool ChannelData::ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config, - const HealthCheckParsedObject** health_check) { + const ParsedLoadBalancingConfig** lb_policy_config) { ChannelData* chand = static_cast(arg); ProcessedResolverResult resolver_result(result); const char* service_config_json = resolver_result.service_config_json(); @@ -1140,7 +1149,6 @@ bool ChannelData::ProcessResolverResultLocked( // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_config = resolver_result.lb_policy_config(); - *health_check = resolver_result.health_check(); return service_config_changed; } diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 43a696da983..883409fbee8 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -34,9 +34,8 @@ class ClientChannelFactory { virtual ~ClientChannelFactory() = default; // Creates a subchannel with the specified args. - virtual Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel(const grpc_channel_args* args) + GRPC_ABSTRACT; // Creates a channel for the specified target with the specified args. virtual grpc_channel* CreateChannel( diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc index 1dcef527861..13bad49c5b6 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -61,6 +61,7 @@ UniquePtr HealthCheckParser::ParseGlobalParams( } } } + if (service_name == nullptr) return nullptr; return UniquePtr( New(service_name)); } diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc index 90ac4d786ca..6fa799343ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy.cc +++ b/src/core/ext/filters/client_channel/lb_policy.cc @@ -69,15 +69,12 @@ void LoadBalancingPolicy::ShutdownAndUnrefLocked(void* arg, LoadBalancingPolicy::UpdateArgs::UpdateArgs(const UpdateArgs& other) { addresses = other.addresses; config = other.config; - health_check = other.health_check; args = grpc_channel_args_copy(other.args); } LoadBalancingPolicy::UpdateArgs::UpdateArgs(UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); - health_check = other.health_check; - other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. args = other.args; other.args = nullptr; @@ -87,7 +84,6 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( const UpdateArgs& other) { addresses = other.addresses; config = other.config; - health_check = other.health_check; grpc_channel_args_destroy(args); args = grpc_channel_args_copy(other.args); return *this; @@ -97,8 +93,6 @@ LoadBalancingPolicy::UpdateArgs& LoadBalancingPolicy::UpdateArgs::operator=( UpdateArgs&& other) { addresses = std::move(other.addresses); config = std::move(other.config); - health_check = other.health_check; - other.health_check = nullptr; // TODO(roth): Use std::move() once channel args is converted to C++. grpc_channel_args_destroy(args); args = other.args; diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index 057222aa14a..b23f77bee7c 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -185,9 +185,8 @@ class LoadBalancingPolicy : public InternallyRefCounted { virtual ~ChannelControlHelper() = default; /// Creates a new subchannel with the specified channel args. - virtual Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) GRPC_ABSTRACT; + virtual Subchannel* CreateSubchannel(const grpc_channel_args& args) + GRPC_ABSTRACT; /// Creates a channel with the specified target and channel args. /// This can be used in cases where the LB policy needs to create a @@ -211,7 +210,6 @@ class LoadBalancingPolicy : public InternallyRefCounted { struct UpdateArgs { ServerAddressList addresses; const ParsedLoadBalancingConfig* config = nullptr; - const HealthCheckParsedObject* health_check = nullptr; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 98c9f81ddda..ba7276747fd 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -292,9 +292,7 @@ class GrpcLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override; + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -619,15 +617,12 @@ bool GrpcLb::Helper::CalledByCurrentChild() const { return child_ == parent_->child_policy_.get(); } -Subchannel* GrpcLb::Helper::CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) { +Subchannel* GrpcLb::Helper::CreateSubchannel(const grpc_channel_args& args) { if (parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return parent_->channel_control_helper()->CreateSubchannel(args, - health_check); + return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* GrpcLb::Helper::CreateChannel(const char* target, diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 899c6f14b6c..398c8efd524 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -88,10 +88,9 @@ class PickFirst : public LoadBalancingPolicy { PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args, health_check) { + policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -256,8 +255,7 @@ void PickFirst::UpdateLocked(UpdateArgs args) { grpc_channel_args* new_args = grpc_channel_args_copy_and_add(args.args, &new_arg, 1); auto subchannel_list = MakeOrphanable( - this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args, - args.health_check); + this, &grpc_lb_pick_first_trace, args.addresses, combiner(), *new_args); grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 76187d0978a..089f57827c7 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -109,10 +109,9 @@ class RoundRobin : public LoadBalancingPolicy { RoundRobinSubchannelList(RoundRobin* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) + const grpc_channel_args& args) : SubchannelList(policy, tracer, addresses, combiner, - policy->channel_control_helper(), args, health_check) { + policy->channel_control_helper(), args) { // Need to maintain a ref to the LB policy as long as we maintain // any references to subchannels, since the subchannels' // pollset_sets will include the LB policy's pollset_set. @@ -481,8 +480,7 @@ void RoundRobin::UpdateLocked(UpdateArgs args) { } } latest_pending_subchannel_list_ = MakeOrphanable( - this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args, - args.health_check); + this, &grpc_lb_round_robin_trace, args.addresses, combiner(), *args.args); if (latest_pending_subchannel_list_->num_subchannels() == 0) { // If the new list is empty, immediately promote the new list to the // current list and transition to TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 51c45d9f87a..004ee04459b 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -232,8 +232,7 @@ class SubchannelList : public InternallyRefCounted { SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check); + const grpc_channel_args& args); virtual ~SubchannelList(); @@ -486,7 +485,7 @@ SubchannelList::SubchannelList( LoadBalancingPolicy* policy, TraceFlag* tracer, const ServerAddressList& addresses, grpc_combiner* combiner, LoadBalancingPolicy::ChannelControlHelper* helper, - const grpc_channel_args& args, const HealthCheckParsedObject* health_check) + const grpc_channel_args& args) : InternallyRefCounted(tracer), policy_(policy), tracer_(tracer), @@ -521,7 +520,7 @@ SubchannelList::SubchannelList( &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add.data(), args_to_add.size()); gpr_free(args_to_add[subchannel_address_arg_index].value.string); - Subchannel* subchannel = helper->CreateSubchannel(*new_args, health_check); + Subchannel* subchannel = helper->CreateSubchannel(*new_args); grpc_channel_args_destroy(new_args); if (subchannel == nullptr) { // Subchannel could not be created. diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 2a00543f593..ce752adaeef 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -323,9 +323,7 @@ class XdsLb : public LoadBalancingPolicy { explicit Helper(RefCountedPtr entry) : entry_(std::move(entry)) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override; + Subchannel* CreateSubchannel(const grpc_channel_args& args) override; grpc_channel* CreateChannel(const char* target, const grpc_channel_args& args) override; void UpdateState(grpc_connectivity_state state, @@ -1574,14 +1572,12 @@ bool XdsLb::LocalityMap::LocalityEntry::Helper::CalledByCurrentChild() const { } Subchannel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) { + const grpc_channel_args& args) { if (entry_->parent_->shutting_down_ || (!CalledByPendingChild() && !CalledByCurrentChild())) { return nullptr; } - return entry_->parent_->channel_control_helper()->CreateSubchannel( - args, health_check); + return entry_->parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* XdsLb::LocalityMap::LocalityEntry::Helper::CreateChannel( diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 97f5e5fda80..34a58358716 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -106,13 +106,10 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper RefCountedPtr parent) : parent_(std::move(parent)) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override { + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { if (parent_->resolver_ == nullptr) return nullptr; // Shutting down. if (!CalledByCurrentChild() && !CalledByPendingChild()) return nullptr; - return parent_->channel_control_helper()->CreateSubchannel(args, - health_check); + return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* CreateChannel(const char* target, @@ -336,8 +333,7 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, Resolver::Result result, - TraceStringVector* trace_strings, - const HealthCheckParsedObject* health_check) { + TraceStringVector* trace_strings) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -430,7 +426,6 @@ void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( UpdateArgs update_args; update_args.addresses = std::move(result.addresses); update_args.config = std::move(lb_policy_config); - update_args.health_check = health_check; // TODO(roth): Once channel args is converted to C++, use std::move() here. update_args.args = result.args; result.args = nullptr; @@ -535,12 +530,11 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( // Process the resolver result. const char* lb_policy_name = nullptr; const ParsedLoadBalancingConfig* lb_policy_config = nullptr; - const HealthCheckParsedObject* health_check = nullptr; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { - service_config_changed = process_resolver_result_( - process_resolver_result_user_data_, result, &lb_policy_name, - &lb_policy_config, &health_check); + service_config_changed = + process_resolver_result_(process_resolver_result_user_data_, result, + &lb_policy_name, &lb_policy_config); } else { lb_policy_name = child_policy_name_.get(); lb_policy_config = child_lb_config_; @@ -548,7 +542,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( GPR_ASSERT(lb_policy_name != nullptr); // Create or update LB policy, as needed. CreateOrUpdateLbPolicyLocked(lb_policy_name, lb_policy_config, - std::move(result), &trace_strings, health_check); + std::move(result), &trace_strings); // Add channel trace event. if (channelz_node() != nullptr) { if (service_config_changed) { diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index 84d134254d0..85fad3093e0 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -68,8 +68,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { typedef bool (*ProcessResolverResultCallback)( void* user_data, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config, - const HealthCheckParsedObject** health_check); + const ParsedLoadBalancingConfig** lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -108,8 +107,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, const ParsedLoadBalancingConfig* lb_policy_config, - Resolver::Result result, TraceStringVector* trace_strings, - const HealthCheckParsedObject* health_check); + Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, TraceStringVector* trace_strings); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index b21fec7cc3f..639d0ec79f4 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -532,8 +532,7 @@ BackOff::Options ParseArgsForBackoffValues( } // namespace Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) + const grpc_channel_args* args) : key_(key), connector_(connector), backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) { @@ -565,10 +564,9 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, "subchannel"); grpc_connectivity_state_init(&state_and_health_tracker_, GRPC_CHANNEL_IDLE, "subchannel"); - if (health_check != nullptr) { - health_check_service_name_ = - UniquePtr(gpr_strdup(health_check->service_name())); - } + health_check_service_name_ = + UniquePtr(gpr_strdup(grpc_channel_arg_get_string( + grpc_channel_args_find(args_, "grpc.temp.health_check")))); const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); const bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); @@ -603,8 +601,7 @@ Subchannel::~Subchannel() { } Subchannel* Subchannel::Create(grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) { + const grpc_channel_args* args) { SubchannelKey* key = New(args); SubchannelPoolInterface* subchannel_pool = SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args); @@ -614,7 +611,7 @@ Subchannel* Subchannel::Create(grpc_connector* connector, Delete(key); return c; } - c = New(key, connector, args, health_check); + c = New(key, connector, args); // Try to register the subchannel before setting the subchannel pool. // Otherwise, in case of a registration race, unreffing c in // RegisterSubchannel() will cause c to be tried to be unregistered, while diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index fb378150160..c67b51a8fa4 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -179,14 +179,12 @@ class Subchannel { public: // The ctor and dtor are not intended to use directly. Subchannel(SubchannelKey* key, grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check); + const grpc_channel_args* args); ~Subchannel(); // Creates a subchannel given \a connector and \a args. static Subchannel* Create(grpc_connector* connector, - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check); + const grpc_channel_args* args); // Strong and weak refcounting. Subchannel* Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS); diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc index ca5a7458e8d..0d61abd2a01 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.cc @@ -37,13 +37,11 @@ namespace grpc_core { class Chttp2InsecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) override { + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { grpc_channel_args* new_args = grpc_default_authority_add_if_not_present(args); grpc_connector* connector = grpc_chttp2_connector_create(); - Subchannel* s = Subchannel::Create(connector, new_args, health_check); + Subchannel* s = Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc index c10d1903dd4..bc38ff25c79 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc @@ -44,9 +44,7 @@ namespace grpc_core { class Chttp2SecureClientChannelFactory : public ClientChannelFactory { public: - Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const HealthCheckParsedObject* health_check) override { + Subchannel* CreateSubchannel(const grpc_channel_args* args) override { grpc_channel_args* new_args = GetSecureNamingChannelArgs(args); if (new_args == nullptr) { gpr_log(GPR_ERROR, @@ -54,7 +52,7 @@ class Chttp2SecureClientChannelFactory : public ClientChannelFactory { return nullptr; } grpc_connector* connector = grpc_chttp2_connector_create(); - Subchannel* s = Subchannel::Create(connector, new_args, health_check); + Subchannel* s = Subchannel::Create(connector, new_args); grpc_connector_unref(connector); grpc_channel_args_destroy(new_args); return s; diff --git a/test/core/util/test_lb_policies.cc b/test/core/util/test_lb_policies.cc index 3daa2733267..b871f04bc9e 100644 --- a/test/core/util/test_lb_policies.cc +++ b/test/core/util/test_lb_policies.cc @@ -141,11 +141,8 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy InterceptRecvTrailingMetadataCallback cb, void* user_data) : parent_(std::move(parent)), cb_(cb), user_data_(user_data) {} - Subchannel* CreateSubchannel( - const grpc_channel_args& args, - const HealthCheckParsedObject* health_check) override { - return parent_->channel_control_helper()->CreateSubchannel(args, - health_check); + Subchannel* CreateSubchannel(const grpc_channel_args& args) override { + return parent_->channel_control_helper()->CreateSubchannel(args); } grpc_channel* CreateChannel(const char* target, diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 075a296dc5b..177b0187cc6 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -322,8 +322,7 @@ static void DoNothing(void* arg, grpc_error* error) {} class FakeClientChannelFactory : public grpc_core::ClientChannelFactory { public: grpc_core::Subchannel* CreateSubchannel( - const grpc_channel_args* args, - const grpc_core::HealthCheckParsedObject* health_check) override { + const grpc_channel_args* args) override { return nullptr; } grpc_channel* CreateChannel(const char* target, From 858b5cca20785f71139281599e523d7ed976efef Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 11:45:11 -0700 Subject: [PATCH 041/112] Fix clang_format_code.sh issues and move the internal calls to new name --- include/grpcpp/create_channel.h | 4 ++-- include/grpcpp/create_channel_impl.h | 4 ++-- include/grpcpp/security/credentials.h | 6 +++--- src/cpp/client/create_channel.cc | 8 ++++---- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 2 +- test/cpp/client/client_channel_stress_test.cc | 4 ++-- test/cpp/end2end/async_end2end_test.cc | 12 ++++++------ test/cpp/end2end/client_callback_end2end_test.cc | 7 ++++--- test/cpp/end2end/end2end_test.cc | 4 ++-- test/cpp/microbenchmarks/fullstack_fixtures.h | 4 ++-- test/cpp/util/create_test_channel.cc | 6 ++++-- 13 files changed, 34 insertions(+), 31 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 6d444be9803..d9d7d432c3f 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -26,14 +26,14 @@ namespace grpc { static inline std::shared_ptr CreateChannel( const grpc::string& target, const std::shared_ptr& creds) { - return ::grpc_impl::CreateChannel(target, creds); + return ::grpc_impl::CreateChannelImpl(target, creds); } static inline std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args) { - return ::grpc_impl::CreateCustomChannel(target, creds, args); + return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); } namespace experimental { diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 214a537a3cb..84dd2f7c765 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -35,7 +35,7 @@ namespace grpc_impl { /// \param creds Credentials to use for the created channel. If it does not /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. -std::shared_ptr CreateChannel( +std::shared_ptr CreateChannelImpl( const grpc::string& target, const std::shared_ptr& creds); @@ -49,7 +49,7 @@ std::shared_ptr CreateChannel( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8662b068a59..03f1f217c18 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -38,7 +38,7 @@ class CallCredentials; class ChannelCredentials; } // namespace grpc namespace grpc_impl { -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -77,7 +77,7 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr grpc_impl::CreateCustomChannel( + friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -91,7 +91,7 @@ class ChannelCredentials : private GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr CreateChannelImpl( const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index c5417de35ea..c366693eced 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -26,19 +26,19 @@ #include "src/cpp/client/create_channel_internal.h" namespace grpc_impl { -std::shared_ptr CreateChannel( +std::shared_ptr CreateChannelImpl( const grpc::string& target, const std::shared_ptr& creds) { - return CreateCustomChannel(target, creds, grpc::ChannelArguments()); + return CreateCustomChannelImpl(target, creds, grpc::ChannelArguments()); } -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args) { grpc::GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds. - return creds ? creds->CreateChannel(target, args) + return creds ? creds->CreateChannelImpl(target, args) : grpc::CreateChannelInternal( "", grpc_lame_client_channel_create( diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 241ce918034..1b0fa6faea9 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -30,7 +30,7 @@ namespace grpc { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 4d0ed355aba..f490f6e6f9a 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -34,7 +34,7 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannel( +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 4918bd5a4d7..fa2f64ed1d8 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -37,7 +37,7 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index fe9aed1766e..7b4d47276ef 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -268,8 +268,8 @@ class ClientChannelStressTest { response_generator_.get()); std::ostringstream uri; uri << "fake:///servername_not_used"; - channel_ = - ::grpc::CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); + channel_ = ::grpc::CreateCustomChannel(uri.str(), + InsecureChannelCredentials(), args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index f8e65ecff41..b16da4c9345 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -294,9 +294,9 @@ class AsyncEnd2endTest : public ::testing::TestWithParam { auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( GetParam().credentials_type, &args); std::shared_ptr channel = - !(GetParam().inproc) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); + !(GetParam().inproc) ? ::grpc::CreateCustomChannel( + server_address_.str(), channel_creds, args) + : server_->InProcessChannel(args); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -1255,9 +1255,9 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials( GetParam().credentials_type, &args); std::shared_ptr channel = - !(GetParam().inproc) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) - : server_->InProcessChannel(args); + !(GetParam().inproc) ? ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args) + : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index fa116b5519e..4e11fc71ca3 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -142,8 +142,8 @@ class ClientCallbackEnd2endTest switch (GetParam().protocol) { case Protocol::TCP: if (!GetParam().use_interceptors) { - channel_ = - ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, @@ -1153,7 +1153,8 @@ TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) { GetParam().credentials_type, &args); std::shared_ptr channel = (GetParam().protocol == Protocol::TCP) - ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args) + ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, + args) : server_->InProcessChannel(args); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index d3f5c3e9187..47231058d17 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -340,8 +340,8 @@ class End2endTest : public ::testing::TestWithParam { if (!GetParam().inproc) { if (!GetParam().use_interceptors) { - channel_ = - ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); } else { channel_ = CreateCustomChannelWithInterceptors( server_address_.str(), channel_creds, args, diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index ed231752438..80ccab3e6ef 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -86,8 +86,8 @@ class FullstackFixture : public BaseFixture { ChannelArguments args; config.ApplyCommonChannelArguments(&args); if (address.length() > 0) { - channel_ = - ::grpc::CreateCustomChannel(address, InsecureChannelCredentials(), args); + channel_ = ::grpc::CreateCustomChannel( + address, InsecureChannelCredentials(), args); } else { channel_ = server_->InProcessChannel(args); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index d036e785360..c0b999b511c 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -132,7 +132,8 @@ std::shared_ptr CreateTestChannel( std::shared_ptr channel_creds; if (cred_type.empty()) { if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), args); + return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), + args); } else { return experimental::CreateCustomChannelWithInterceptors( server, InsecureChannelCredentials(), args, @@ -159,7 +160,8 @@ std::shared_ptr CreateTestChannel( channel_creds = CompositeChannelCredentials(channel_creds, creds); } if (interceptor_creators.empty()) { - return ::grpc::CreateCustomChannel(connect_to, channel_creds, channel_args); + return ::grpc::CreateCustomChannel(connect_to, channel_creds, + channel_args); } else { return experimental::CreateCustomChannelWithInterceptors( connect_to, channel_creds, channel_args, From edd817a46fe0f6a257ecdc28745494ce9668de68 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 23 Apr 2019 12:10:08 -0700 Subject: [PATCH 042/112] Reviewer comments --- BUILD | 2 - BUILD.gn | 2 - CMakeLists.txt | 6 -- Makefile | 6 -- build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - .../filters/client_channel/client_channel.cc | 35 ++++---- .../client_channel/client_channel_plugin.cc | 1 - .../client_channel/resolver_result_parsing.cc | 9 +- .../client_channel/resolver_result_parsing.h | 2 +- .../filters/client_channel/service_config.h | 27 ++++++ .../ext/filters/client_channel/subchannel.cc | 1 + .../message_size/message_size_filter.cc | 80 ++++++++++++++++-- .../message_size/message_size_filter.h | 32 +++++++ .../message_size/message_size_parser.cc | 84 ------------------- .../message_size/message_size_parser.h | 55 ------------ src/core/lib/channel/context.h | 5 +- src/core/lib/iomgr/error.h | 1 - src/python/grpcio/grpc_core_dependencies.py | 1 - tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 7 +- 27 files changed, 153 insertions(+), 221 deletions(-) delete mode 100644 src/core/ext/filters/message_size/message_size_parser.cc delete mode 100644 src/core/ext/filters/message_size/message_size_parser.h diff --git a/BUILD b/BUILD index 07db0019138..7f99bcdfaca 100644 --- a/BUILD +++ b/BUILD @@ -1099,7 +1099,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/service_config.cc", "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", - "src/core/ext/filters/message_size/message_size_parser.cc", ], hdrs = [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -1129,7 +1128,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.h", - "src/core/ext/filters/message_size/message_size_parser.h", ], language = "c++", deps = [ diff --git a/BUILD.gn b/BUILD.gn index d75dce49080..e83def5507d 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -354,8 +354,6 @@ config("grpc_config") { "src/core/ext/filters/max_age/max_age_filter.h", "src/core/ext/filters/message_size/message_size_filter.cc", "src/core/ext/filters/message_size/message_size_filter.h", - "src/core/ext/filters/message_size/message_size_parser.cc", - "src/core/ext/filters/message_size/message_size_parser.h", "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc", "src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h", "src/core/ext/filters/workarounds/workaround_utils.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 56ccbffd0c1..b221b4e7cd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1252,7 +1252,6 @@ add_library(grpc src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/fake_transport_security.cc @@ -1609,7 +1608,6 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -1991,7 +1989,6 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2318,7 +2315,6 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -2656,7 +2652,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/filters/client_channel/health/health.pb.c third_party/nanopb/pb_common.c @@ -3528,7 +3523,6 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/service_config.cc src/core/ext/filters/client_channel/subchannel.cc src/core/ext/filters/client_channel/subchannel_pool_interface.cc - src/core/ext/filters/message_size/message_size_parser.cc src/core/ext/filters/deadline/deadline_filter.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc diff --git a/Makefile b/Makefile index 1b371a8431f..4f9acb9fc1f 100644 --- a/Makefile +++ b/Makefile @@ -3708,7 +3708,6 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ @@ -4059,7 +4058,6 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4434,7 +4432,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -4748,7 +4745,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5060,7 +5056,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ third_party/nanopb/pb_common.c \ @@ -5908,7 +5903,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.cc \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc \ diff --git a/build.yaml b/build.yaml index 936cd911b31..a180c8c1d28 100644 --- a/build.yaml +++ b/build.yaml @@ -596,7 +596,6 @@ filegroups: - src/core/ext/filters/client_channel/service_config.h - src/core/ext/filters/client_channel/subchannel.h - src/core/ext/filters/client_channel/subchannel_pool_interface.h - - src/core/ext/filters/message_size/message_size_parser.h src: - src/core/ext/filters/client_channel/backup_poller.cc - src/core/ext/filters/client_channel/channel_connectivity.cc @@ -625,7 +624,6 @@ filegroups: - src/core/ext/filters/client_channel/service_config.cc - src/core/ext/filters/client_channel/subchannel.cc - src/core/ext/filters/client_channel/subchannel_pool_interface.cc - - src/core/ext/filters/message_size/message_size_parser.cc plugin: grpc_client_channel uses: - grpc_base diff --git a/config.m4 b/config.m4 index 0710e1e8341..e7d3a5daf4e 100644 --- a/config.m4 +++ b/config.m4 @@ -366,7 +366,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/service_config.cc \ src/core/ext/filters/client_channel/subchannel.cc \ src/core/ext/filters/client_channel/subchannel_pool_interface.cc \ - src/core/ext/filters/message_size/message_size_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/fake_transport_security.cc \ diff --git a/config.w32 b/config.w32 index e69f71dbfb3..8a6529faae2 100644 --- a/config.w32 +++ b/config.w32 @@ -341,7 +341,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\service_config.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel.cc " + "src\\core\\ext\\filters\\client_channel\\subchannel_pool_interface.cc " + - "src\\core\\ext\\filters\\message_size\\message_size_parser.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\fake_transport_security.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index d4f4b626011..782d86a6fcb 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -385,7 +385,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', - 'src/core/ext/filters/message_size/message_size_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index aa38487e194..13c2a2cf9d0 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -367,7 +367,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', - 'src/core/ext/filters/message_size/message_size_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', @@ -816,7 +815,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', - 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -1013,7 +1011,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/service_config.h', 'src/core/ext/filters/client_channel/subchannel.h', 'src/core/ext/filters/client_channel/subchannel_pool_interface.h', - 'src/core/ext/filters/message_size/message_size_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/fake_transport_security.h', diff --git a/grpc.gemspec b/grpc.gemspec index 9749cc69e47..bca4674c761 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -301,7 +301,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/service_config.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel.h ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.h ) - s.files += %w( src/core/ext/filters/message_size/message_size_parser.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) @@ -753,7 +752,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/service_config.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel.cc ) s.files += %w( src/core/ext/filters/client_channel/subchannel_pool_interface.cc ) - s.files += %w( src/core/ext/filters/message_size/message_size_parser.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/fake_transport_security.cc ) diff --git a/grpc.gyp b/grpc.gyp index 874cc5a52bf..d4db059dc0a 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -548,7 +548,6 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', - 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', @@ -814,7 +813,6 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', - 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1061,7 +1059,6 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', - 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', @@ -1319,7 +1316,6 @@ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', - 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'third_party/nanopb/pb_common.c', diff --git a/package.xml b/package.xml index 66bf5ee8863..3af95c9a727 100644 --- a/package.xml +++ b/package.xml @@ -306,7 +306,6 @@ - @@ -758,7 +757,6 @@ - diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index ffb2b9a904b..99ffeeaa522 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -618,7 +618,7 @@ class CallData { grpc_call_context_element* call_context_; RefCountedPtr retry_throttle_data_; - RefCountedPtr service_config_; + ServiceConfig::CallData service_config_call_data_; const ClientChannelMethodParsedObject* method_params_ = nullptr; RefCountedPtr subchannel_call_; @@ -935,7 +935,7 @@ class ChannelData::ClientChannelControlHelper grpc_arg args_to_add[2]; int num_args_to_add = 0; if (chand_->service_config_ != nullptr) { - /*const auto* health_check_object = static_cast( + const auto* health_check_object = static_cast( chand_->service_config_->GetParsedGlobalServiceConfigObject( HealthCheckParser::ParserIndex())); if (health_check_object != nullptr) { @@ -943,7 +943,7 @@ class ChannelData::ClientChannelControlHelper const_cast("grpc.temp.health_check"), const_cast(health_check_object->service_name())); num_args_to_add++; - }*/ + } } args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); @@ -3087,24 +3087,17 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call", chand, this); } - service_config_ = chand->service_config(); - if (service_config_ != nullptr) { - // Store a ref to the service_config in CallData. Also, save pointers to the - // ServiceConfig and ServiceConfigObjectsVector (for this call) in the - // call_context so that all future filters can access it. - call_context_[GRPC_SERVICE_CONFIG].value = &service_config_; - const auto* method_params_vector_ptr = - service_config_->GetMethodServiceConfigObjectsVector(path_); - if (method_params_vector_ptr != nullptr) { - method_params_ = static_cast( - ((*method_params_vector_ptr) - [internal::ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index()]) - .get()); - call_context_[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value = - const_cast( - method_params_vector_ptr); - } + // Store a ref to the service_config in service_config_call_data_. Also, save + // a pointer to this in the call_context so that all future filters can access + // it. + service_config_call_data_ = + ServiceConfig::CallData(chand->service_config(), path_); + if (!service_config_call_data_.empty()) { + call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value = + &service_config_call_data_; + method_params_ = static_cast( + service_config_call_data_.GetMethodParsedObject( + internal::ClientChannelServiceConfigParser::ParserIndex())); } retry_throttle_data_ = chand->retry_throttle_data(); if (method_params_ != nullptr) { diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index a5d2c83ecd3..877111b8a38 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -35,7 +35,6 @@ #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/retry_throttle.h" -#include "src/core/ext/filters/message_size/message_size_parser.h" #include "src/core/lib/surface/channel_init.h" static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 2d5a5bb8e2d..e4a36119c3f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -48,8 +48,7 @@ namespace { size_t g_client_channel_service_config_parser_index; } -size_t -ClientChannelServiceConfigParser::client_channel_service_config_parser_index() { +size_t ClientChannelServiceConfigParser::ParserIndex() { return g_client_channel_service_config_parser_index; } @@ -87,8 +86,7 @@ void ProcessedResolverResult::ProcessServiceConfig( service_config_json_ = service_config_->service_config_json(); auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( - ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index())); + ClientChannelServiceConfigParser::ParserIndex())); if (!parsed_object) { return; } @@ -113,8 +111,7 @@ void ProcessedResolverResult::ProcessLbPolicy( if (service_config_ != nullptr) { auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( - ClientChannelServiceConfigParser:: - client_channel_service_config_parser_index())); + ClientChannelServiceConfigParser::ParserIndex())); if (parsed_object != nullptr) { if (parsed_object->parsed_lb_config()) { lb_policy_name_.reset( diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 02a49bad2e9..0369e0b704f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -107,7 +107,7 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser { UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override; - static size_t client_channel_service_config_parser_index(); + static size_t ParserIndex(); static void Register(); }; diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 0b7a8d33855..85a49855f96 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -91,6 +91,33 @@ class ServiceConfig : public RefCounted { kNumPreallocatedParsers> ServiceConfigObjectsVector; + class CallData { + public: + CallData() = default; + CallData(RefCountedPtr svc_cfg, const grpc_slice& path) + : service_config_(std::move(svc_cfg)) { + if (service_config_ != nullptr) { + method_params_vector_ = + service_config_->GetMethodServiceConfigObjectsVector(path); + } + } + + RefCountedPtr service_config() { return service_config_; } + + ServiceConfigParsedObject* GetMethodParsedObject(int index) const { + return method_params_vector_ != nullptr + ? (*method_params_vector_)[index].get() + : nullptr; + } + + bool empty() const { return service_config_ == nullptr; } + + private: + RefCountedPtr service_config_; + const ServiceConfig::ServiceConfigObjectsVector* method_params_vector_ = + nullptr; + }; + /// Creates a new service config from parsing \a json_string. /// Returns null on parse error. static RefCountedPtr Create(const char* json, diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index 639d0ec79f4..e7f22b07ae9 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -567,6 +567,7 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, health_check_service_name_ = UniquePtr(gpr_strdup(grpc_channel_arg_get_string( grpc_channel_args_find(args_, "grpc.temp.health_check")))); + gpr_log(GPR_ERROR, "healthcheck %s", health_check_service_name_.get()); const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); const bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index d7bfa28fee1..e19accbe8a7 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -26,7 +26,7 @@ #include #include -#include "src/core/ext/filters/message_size/message_size_parser.h" +#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/gpr/string.h" @@ -38,6 +38,69 @@ static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); +namespace { +size_t g_message_size_parser_index; +} // namespace + +namespace grpc_core { + +UniquePtr MessageSizeParser::ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + InlinedVector error_list; + for (grpc_json* field = json->child; field != nullptr; field = field->next) { + if (field->key == nullptr) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be of type number")); + } else { + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxRequestMessageBytes error:should be non-negative")); + } + } + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:Duplicate entry")); + } else if (field->type != GRPC_JSON_STRING && + field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be of type number")); + } else { + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:maxResponseMessageBytes error:should be non-negative")); + } + } + } + } + if (!error_list.empty()) { + *error = ServiceConfig::CreateErrorFromVector("Message size parser", + &error_list); + return nullptr; + } + return UniquePtr(New( + max_request_message_bytes, max_response_message_bytes)); +} + +void MessageSizeParser::Register() { + g_message_size_parser_index = ServiceConfig::RegisterParser( + UniquePtr(New())); +} + +size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } +} // namespace grpc_core + namespace { struct channel_data { grpc_core::MessageSizeParsedObject::message_size_limits limits; @@ -58,18 +121,17 @@ struct call_data { // apply the max request size to the send limit and the max response // size to the receive limit. const grpc_core::MessageSizeParsedObject* limits = nullptr; - const grpc_core::ServiceConfig::ServiceConfigObjectsVector* objs_vector = - nullptr; + grpc_core::ServiceConfig::CallData* svc_cfg_call_data = nullptr; if (args.context != nullptr) { - objs_vector = static_cast< - const grpc_core::ServiceConfig::ServiceConfigObjectsVector*>( - args.context[GRPC_SERVICE_CONFIG_METHOD_PARAMS].value); + svc_cfg_call_data = static_cast( + args.context[GRPC_SERVICE_CONFIG_CALL_DATA].value); } - if (objs_vector != nullptr) { + if (svc_cfg_call_data != nullptr) { limits = static_cast( - (*objs_vector)[grpc_core::MessageSizeParser::ParserIndex()].get()); + svc_cfg_call_data->GetMethodParsedObject( + grpc_core::MessageSizeParser::ParserIndex())); } else if (chand.svc_cfg != nullptr) { - objs_vector = + const auto* objs_vector = chand.svc_cfg->GetMethodServiceConfigObjectsVector(args.path); if (objs_vector != nullptr) { limits = static_cast( diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index b916bdd83f6..e43d7be61b5 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -24,4 +24,36 @@ extern const grpc_channel_filter grpc_message_size_filter; +namespace grpc_core { + +class MessageSizeParsedObject : public ServiceConfigParsedObject { + public: + struct message_size_limits { + int max_send_size; + int max_recv_size; + }; + + MessageSizeParsedObject(int max_send_size, int max_recv_size) { + limits_.max_send_size = max_send_size; + limits_.max_recv_size = max_recv_size; + } + + const message_size_limits& limits() const { return limits_; } + + private: + message_size_limits limits_; +}; + +class MessageSizeParser : public ServiceConfigParser { + public: + UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) override; + + static void Register(); + + static size_t ParserIndex(); +}; + +} // namespace grpc_core + #endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_FILTER_H */ diff --git a/src/core/ext/filters/message_size/message_size_parser.cc b/src/core/ext/filters/message_size/message_size_parser.cc deleted file mode 100644 index a3444a984dd..00000000000 --- a/src/core/ext/filters/message_size/message_size_parser.cc +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2019 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include - -#include "src/core/ext/filters/message_size/message_size_parser.h" - -#include "src/core/lib/gpr/string.h" - -namespace { -size_t g_message_size_parser_index; -} // namespace - -namespace grpc_core { - -UniquePtr MessageSizeParser::ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - int max_request_message_bytes = -1; - int max_response_message_bytes = -1; - InlinedVector error_list; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) continue; - if (strcmp(field->key, "maxRequestMessageBytes") == 0) { - if (max_request_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be of type number")); - } else { - max_request_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_request_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxRequestMessageBytes error:should be non-negative")); - } - } - } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { - if (max_response_message_bytes >= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be of type number")); - } else { - max_response_message_bytes = gpr_parse_nonnegative_int(field->value); - if (max_response_message_bytes == -1) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxResponseMessageBytes error:should be non-negative")); - } - } - } - } - if (!error_list.empty()) { - *error = ServiceConfig::CreateErrorFromVector("Message size parser", - &error_list); - return nullptr; - } - return UniquePtr(New( - max_request_message_bytes, max_response_message_bytes)); -} - -void MessageSizeParser::Register() { - g_message_size_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); -} - -size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } -} // namespace grpc_core diff --git a/src/core/ext/filters/message_size/message_size_parser.h b/src/core/ext/filters/message_size/message_size_parser.h deleted file mode 100644 index 4581cdf6226..00000000000 --- a/src/core/ext/filters/message_size/message_size_parser.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2019 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#ifndef GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H -#define GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H - -#include - -#include "src/core/ext/filters/client_channel/service_config.h" - -namespace grpc_core { - -class MessageSizeParsedObject : public ServiceConfigParsedObject { - public: - struct message_size_limits { - int max_send_size; - int max_recv_size; - }; - - MessageSizeParsedObject(int max_send_size, int max_recv_size) { - limits_.max_send_size = max_send_size; - limits_.max_recv_size = max_recv_size; - } - - const message_size_limits& limits() const { return limits_; } - - private: - message_size_limits limits_; -}; - -class MessageSizeParser : public ServiceConfigParser { - public: - UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) override; - - static void Register(); - - static size_t ParserIndex(); -}; -} // namespace grpc_core - -#endif /* GRPC_CORE_EXT_FILTERS_MESSAGE_SIZE_MESSAGE_SIZE_PARSER_H */ diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index 3c91f9365f8..fd9d0ce711a 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -35,9 +35,8 @@ typedef enum { /// Reserved for traffic_class_context. GRPC_CONTEXT_TRAFFIC, - GRPC_SERVICE_CONFIG, - - GRPC_SERVICE_CONFIG_METHOD_PARAMS, + /// Holds a pointer to ServiceConfig::CallData associated with this call. + GRPC_SERVICE_CONFIG_CALL_DATA, GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 99a148ddc26..fcc6f0761b3 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,7 +30,6 @@ #include #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 6aa0a37826e..8060b5a0a8c 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -340,7 +340,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/service_config.cc', 'src/core/ext/filters/client_channel/subchannel.cc', 'src/core/ext/filters/client_channel/subchannel_pool_interface.cc', - 'src/core/ext/filters/message_size/message_size_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/fake_transport_security.cc', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 88e57036830..eee3f777ea6 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -989,8 +989,6 @@ src/core/ext/filters/max_age/max_age_filter.cc \ src/core/ext/filters/max_age/max_age_filter.h \ src/core/ext/filters/message_size/message_size_filter.cc \ src/core/ext/filters/message_size/message_size_filter.h \ -src/core/ext/filters/message_size/message_size_parser.cc \ -src/core/ext/filters/message_size/message_size_parser.h \ src/core/ext/filters/workarounds/workaround_cronet_compression_filter.cc \ src/core/ext/filters/workarounds/workaround_cronet_compression_filter.h \ src/core/ext/filters/workarounds/workaround_utils.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 3b66e146262..6a0d47ab932 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8733,8 +8733,7 @@ "src/core/ext/filters/client_channel/server_address.h", "src/core/ext/filters/client_channel/service_config.h", "src/core/ext/filters/client_channel/subchannel.h", - "src/core/ext/filters/client_channel/subchannel_pool_interface.h", - "src/core/ext/filters/message_size/message_size_parser.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "is_filegroup": true, "language": "c", @@ -8793,9 +8792,7 @@ "src/core/ext/filters/client_channel/subchannel.cc", "src/core/ext/filters/client_channel/subchannel.h", "src/core/ext/filters/client_channel/subchannel_pool_interface.cc", - "src/core/ext/filters/client_channel/subchannel_pool_interface.h", - "src/core/ext/filters/message_size/message_size_parser.cc", - "src/core/ext/filters/message_size/message_size_parser.h" + "src/core/ext/filters/client_channel/subchannel_pool_interface.h" ], "third_party": false, "type": "filegroup" From 76d78eb82b59c2eae4f3669d464928d0071c519a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 14:27:30 -0700 Subject: [PATCH 043/112] Moving create_channel from grpc to grpc_impl --- include/grpcpp/security/credentials.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 03f1f217c18..e4cc1c7d501 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -35,6 +35,7 @@ struct grpc_call; namespace grpc { class CallCredentials; +class ChannelArguments; class ChannelCredentials; } // namespace grpc namespace grpc_impl { @@ -77,12 +78,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( + friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -91,12 +92,12 @@ class ChannelCredentials : private GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannelImpl( + virtual std::shared_ptr CreateChannelImpl( const grpc::string& target, const ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr CreateChannelWithInterceptors( + virtual std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const ChannelArguments& args, std::vector< std::unique_ptr> From 603d014f0e954e9eb5ea97dd162ffdc3627f79dc Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 19 Mar 2019 14:26:31 -0700 Subject: [PATCH 044/112] Changes to fold credentials into grpc_impl from grpc --- BUILD | 1 + include/grpcpp/impl/codegen/client_context.h | 9 +- include/grpcpp/security/credentials.h | 293 ++++-------------- include/grpcpp/security/credentials_impl.h | 285 +++++++++++++++++ src/cpp/client/create_channel.cc | 1 + src/cpp/client/credentials_cc.cc | 4 +- src/cpp/client/insecure_credentials.cc | 16 +- src/cpp/client/secure_credentials.cc | 62 ++-- src/cpp/client/secure_credentials.h | 10 +- test/cpp/end2end/client_crash_test.cc | 2 +- test/cpp/end2end/end2end_test.cc | 22 +- test/cpp/end2end/filter_end2end_test.cc | 2 +- test/cpp/end2end/generic_end2end_test.cc | 2 +- .../end2end/health_service_end2end_test.cc | 2 +- test/cpp/end2end/hybrid_end2end_test.cc | 6 +- test/cpp/end2end/mock_test.cc | 2 +- test/cpp/end2end/nonblocking_test.cc | 2 +- .../end2end/proto_server_reflection_test.cc | 2 +- test/cpp/end2end/raw_end2end_test.cc | 2 +- .../cpp/end2end/server_builder_plugin_test.cc | 2 +- test/cpp/end2end/server_early_return_test.cc | 2 +- .../server_interceptors_end2end_test.cc | 18 +- .../server_load_reporting_end2end_test.cc | 2 +- test/cpp/end2end/streaming_throughput_test.cc | 2 +- test/cpp/end2end/thread_stress_test.cc | 2 +- test/cpp/end2end/time_change_test.cc | 2 +- test/cpp/qps/driver.cc | 6 +- test/cpp/server/server_request_call_test.cc | 2 +- test/cpp/util/cli_call_test.cc | 2 +- test/cpp/util/create_test_channel.cc | 8 +- test/cpp/util/grpc_tool_test.cc | 2 +- test/cpp/util/test_credentials_provider.cc | 2 +- 32 files changed, 454 insertions(+), 323 deletions(-) create mode 100644 include/grpcpp/security/credentials_impl.h diff --git a/BUILD b/BUILD index 3c0974f3255..2f1ee9f2a5e 100644 --- a/BUILD +++ b/BUILD @@ -252,6 +252,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 7f6956a0da4..f5bcdfa5403 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -57,12 +57,15 @@ struct census_context; struct grpc_call; +namespace grpc_impl { + +class CallCredentials; +} namespace grpc { class Channel; class ChannelInterface; class CompletionQueue; -class CallCredentials; class ClientContext; namespace internal { @@ -306,7 +309,7 @@ class ClientContext { /// call. /// /// \see https://grpc.io/docs/guides/auth.html - void set_credentials(const std::shared_ptr& creds) { + void set_credentials(const std::shared_ptr& creds) { creds_ = creds; } @@ -465,7 +468,7 @@ class ClientContext { bool call_canceled_; gpr_timespec deadline_; grpc::string authority_; - std::shared_ptr creds_; + std::shared_ptr creds_; mutable std::shared_ptr auth_context_; struct census_context* census_context_; std::multimap send_initial_metadata_; diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index e4cc1c7d501..8c99aab6c59 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -19,265 +19,92 @@ #ifndef GRPCPP_SECURITY_CREDENTIALS_H #define GRPCPP_SECURITY_CREDENTIALS_H -#include -#include -#include +#include -#include -#include -#include -#include -#include -#include -#include - -struct grpc_call; - -namespace grpc { -class CallCredentials; -class ChannelArguments; -class ChannelCredentials; -} // namespace grpc -namespace grpc_impl { -std::shared_ptr CreateCustomChannelImpl( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); - -namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators); -} // namespace experimental -} // namespace grpc_impl namespace grpc { class Channel; -class SecureChannelCredentials; -class SecureCallCredentials; - -/// A channel credentials object encapsulates all the state needed by a client -/// to authenticate with a server for a given channel. -/// It can make various assertions, e.g., about the client’s identity, role -/// for all the calls on that channel. -/// -/// \see https://grpc.io/docs/guides/auth.html -class ChannelCredentials : private GrpcLibraryCodegen { - public: - ChannelCredentials(); - ~ChannelCredentials(); - - protected: - friend std::shared_ptr CompositeChannelCredentials( - const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); - - virtual SecureChannelCredentials* AsSecureCredentials() = 0; - - private: - friend std::shared_ptr grpc_impl::CreateCustomChannelImpl( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); - - friend std::shared_ptr - grpc_impl::experimental::CreateCustomChannelWithInterceptors( - const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args, - std::vector> - interceptor_creators); - - virtual std::shared_ptr CreateChannelImpl( - const grpc::string& target, const ChannelArguments& args) = 0; - // This function should have been a pure virtual function, but it is - // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr CreateChannelWithInterceptors( - const grpc::string& target, const ChannelArguments& args, - std::vector< - std::unique_ptr> - interceptor_creators) { - return nullptr; - } -}; +typedef ::grpc_impl::ChannelCredentials ChannelCredentials; +typedef ::grpc_impl::CallCredentials CallCredentials; +typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; +typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; +typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; -/// A call credentials object encapsulates the state needed by a client to -/// authenticate with a server for a given call on a channel. -/// -/// \see https://grpc.io/docs/guides/auth.html -class CallCredentials : private GrpcLibraryCodegen { - public: - CallCredentials(); - ~CallCredentials(); +static inline std::shared_ptr GoogleDefaultCredentials() { + return ::grpc_impl::GoogleDefaultCredentials(); +} - /// Apply this instance's credentials to \a call. - virtual bool ApplyToCall(grpc_call* call) = 0; +static inline std::shared_ptr SslCredentials( + const SslCredentialsOptions& options) { + return ::grpc_impl::SslCredentials(options); +} - protected: - friend std::shared_ptr CompositeChannelCredentials( - const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); +static inline std::shared_ptr GoogleComputeEngineCredentials() { + return ::grpc_impl::GoogleComputeEngineCredentials(); +} - friend std::shared_ptr CompositeCallCredentials( - const std::shared_ptr& creds1, - const std::shared_ptr& creds2); - - virtual SecureCallCredentials* AsSecureCredentials() = 0; -}; - -/// Options used to build SslCredentials. -struct SslCredentialsOptions { - /// The buffer containing the PEM encoding of the server root certificates. If - /// this parameter is empty, the default roots will be used. The default - /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH - /// environment variable pointing to a file on the file system containing the - /// roots. - grpc::string pem_root_certs; - - /// The buffer containing the PEM encoding of the client's private key. This - /// parameter can be empty if the client does not have a private key. - grpc::string pem_private_key; - - /// The buffer containing the PEM encoding of the client's certificate chain. - /// This parameter can be empty if the client does not have a certificate - /// chain. - grpc::string pem_cert_chain; -}; - -// Factories for building different types of Credentials The functions may -// return empty shared_ptr when credentials cannot be created. If a -// Credentials pointer is returned, it can still be invalid when used to create -// a channel. A lame channel will be created then and all rpcs will fail on it. - -/// Builds credentials with reasonable defaults. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleDefaultCredentials(); - -/// Builds SSL Credentials given SSL specific options -std::shared_ptr SslCredentials( - const SslCredentialsOptions& options); - -/// Builds credentials for use when running in GCE -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleComputeEngineCredentials(); - -/// Constant for maximum auth token lifetime. -constexpr long kMaxAuthTokenLifetimeSecs = 3600; - -/// Builds Service Account JWT Access credentials. -/// json_key is the JSON key string containing the client's private key. -/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token -/// (JWT) created with this credentials. It should not exceed -/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. -std::shared_ptr ServiceAccountJWTAccessCredentials( +static inline std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + long token_lifetime_seconds = ::grpc_impl::kMaxAuthTokenLifetimeSecs) { + return ::grpc_impl::ServiceAccountJWTAccessCredentials(json_key, token_lifetime_seconds); +} -/// Builds refresh token credentials. -/// json_refresh_token is the JSON string containing the refresh token along -/// with a client_id and client_secret. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleRefreshTokenCredentials( - const grpc::string& json_refresh_token); +static inline std::shared_ptr GoogleRefreshTokenCredentials( + const grpc::string& json_refresh_token) { + return ::grpc_impl::GoogleRefreshTokenCredentials(json_refresh_token); +} -/// Builds access token credentials. -/// access_token is an oauth2 access token that was fetched using an out of band -/// mechanism. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr AccessTokenCredentials( - const grpc::string& access_token); +static inline std::shared_ptr AccessTokenCredentials( + const grpc::string& access_token) { + return ::grpc_impl::AccessTokenCredentials(access_token); +} -/// Builds IAM credentials. -/// -/// \warning Only use these credentials when connecting to a Google endpoint. -/// Using these credentials to connect to any other service may result in this -/// service being able to impersonate your client for requests to Google -/// services. -std::shared_ptr GoogleIAMCredentials( +static inline std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, - const grpc::string& authority_selector); + const grpc::string& authority_selector) { + return ::grpc_impl::GoogleIAMCredentials(authorization_token, authority_selector); +} -/// Combines a channel credentials and a call credentials into a composite -/// channel credentials. -std::shared_ptr CompositeChannelCredentials( +static inline std::shared_ptr CompositeChannelCredentials( const std::shared_ptr& channel_creds, - const std::shared_ptr& call_creds); + const std::shared_ptr& call_creds) { + return ::grpc_impl::CompositeChannelCredentials(channel_creds, call_creds); +} -/// Combines two call credentials objects into a composite call credentials. -std::shared_ptr CompositeCallCredentials( +static inline std::shared_ptr CompositeCallCredentials( const std::shared_ptr& creds1, - const std::shared_ptr& creds2); - -/// Credentials for an unencrypted, unauthenticated channel -std::shared_ptr InsecureChannelCredentials(); - -/// Credentials for a channel using Cronet. -std::shared_ptr CronetChannelCredentials(void* engine); - -/// User defined metadata credentials. -class MetadataCredentialsPlugin { - public: - virtual ~MetadataCredentialsPlugin() {} + const std::shared_ptr& creds2) { + return ::grpc_impl::CompositeCallCredentials(creds1, creds2); +} - /// If this method returns true, the Process function will be scheduled in - /// a different thread from the one processing the call. - virtual bool IsBlocking() const { return true; } +static inline std::shared_ptr InsecureChannelCredentials() { + return ::grpc_impl::InsecureChannelCredentials(); +} - /// Type of credentials this plugin is implementing. - virtual const char* GetType() const { return ""; } +static inline std::shared_ptr CronetChannelCredentials(void* engine) { + return ::grpc_impl::CronetChannelCredentials(engine); +} - /// Gets the auth metatada produced by this plugin. - /// The fully qualified method name is: - /// service_url + "/" + method_name. - /// The channel_auth_context contains (among other things), the identity of - /// the server. - virtual Status GetMetadata( - grpc::string_ref service_url, grpc::string_ref method_name, - const AuthContext& channel_auth_context, - std::multimap* metadata) = 0; -}; +typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; -std::shared_ptr MetadataCredentialsFromPlugin( - std::unique_ptr plugin); +static inline std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin) { + return ::grpc_impl::MetadataCredentialsFromPlugin(std::move(plugin)); +} namespace experimental { -/// Options used to build AltsCredentials. -struct AltsCredentialsOptions { - /// service accounts of target endpoint that will be acceptable - /// by the client. If service accounts are provided and none of them matches - /// that of the server, authentication will fail. - std::vector target_service_accounts; -}; +typedef ::grpc_impl::experimental::AltsCredentialsOptions AltsCredentialsOptions; -/// Builds ALTS Credentials given ALTS specific options -std::shared_ptr AltsCredentials( - const AltsCredentialsOptions& options); +static inline std::shared_ptr AltsCredentials( + const AltsCredentialsOptions& options) { + return ::grpc_impl::experimental::AltsCredentials(options); +} -/// Builds Local Credentials. -std::shared_ptr LocalCredentials( - grpc_local_connect_type type); +static inline std::shared_ptr LocalCredentials( + grpc_local_connect_type type) { + return ::grpc_impl::experimental::LocalCredentials(type); +} } // namespace experimental } // namespace grpc diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h new file mode 100644 index 00000000000..8ec339639b5 --- /dev/null +++ b/include/grpcpp/security/credentials_impl.h @@ -0,0 +1,285 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPCPP_SECURITY_CREDENTIALS_IMPL_H +#define GRPCPP_SECURITY_CREDENTIALS_IMPL_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +struct grpc_call; + +namespace grpc { +class ChannelArguments; +class Channel; +} // namespace grpc + +namespace grpc_impl { + +class ChannelCredentials; +class CallCredentials; +class SecureCallCredentials; +class SecureChannelCredentials; + +std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); + +namespace experimental { +std::shared_ptr CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); +} + +/// A channel credentials object encapsulates all the state needed by a client +/// to authenticate with a server for a given channel. +/// It can make various assertions, e.g., about the client’s identity, role +/// for all the calls on that channel. +/// +/// \see https://grpc.io/docs/guides/auth.html +class ChannelCredentials : private grpc::GrpcLibraryCodegen { + public: + ChannelCredentials(); + ~ChannelCredentials(); + + protected: + friend std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + + virtual SecureChannelCredentials* AsSecureCredentials() = 0; + + private: + friend std::shared_ptr CreateCustomChannel( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args); + + friend std::shared_ptr + grpc_impl::experimental::CreateCustomChannelWithInterceptors( + const grpc::string& target, + const std::shared_ptr& creds, + const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators); + + virtual std::shared_ptr CreateChannel( + const grpc::string& target, const grpc::ChannelArguments& args) = 0; + + // This function should have been a pure virtual function, but it is + // implemented as a virtual function so that it does not break API. + virtual std::shared_ptr CreateChannelWithInterceptors( + const grpc::string& target, const grpc::ChannelArguments& args, + std::vector< + std::unique_ptr> + interceptor_creators) { + return nullptr; + } +}; + +/// A call credentials object encapsulates the state needed by a client to +/// authenticate with a server for a given call on a channel. +/// +/// \see https://grpc.io/docs/guides/auth.html +class CallCredentials : private grpc::GrpcLibraryCodegen { + public: + CallCredentials(); + ~CallCredentials(); + + /// Apply this instance's credentials to \a call. + virtual bool ApplyToCall(grpc_call* call) = 0; + + protected: + friend std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + + friend std::shared_ptr CompositeCallCredentials( + const std::shared_ptr& creds1, + const std::shared_ptr& creds2); + + virtual SecureCallCredentials* AsSecureCredentials() = 0; +}; + +/// Options used to build SslCredentials. +struct SslCredentialsOptions { + /// The buffer containing the PEM encoding of the server root certificates. If + /// this parameter is empty, the default roots will be used. The default + /// roots can be overridden using the \a GRPC_DEFAULT_SSL_ROOTS_FILE_PATH + /// environment variable pointing to a file on the file system containing the + /// roots. + grpc::string pem_root_certs; + + /// The buffer containing the PEM encoding of the client's private key. This + /// parameter can be empty if the client does not have a private key. + grpc::string pem_private_key; + + /// The buffer containing the PEM encoding of the client's certificate chain. + /// This parameter can be empty if the client does not have a certificate + /// chain. + grpc::string pem_cert_chain; +}; + +// Factories for building different types of Credentials The functions may +// return empty shared_ptr when credentials cannot be created. If a +// Credentials pointer is returned, it can still be invalid when used to create +// a channel. A lame channel will be created then and all rpcs will fail on it. + +/// Builds credentials with reasonable defaults. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleDefaultCredentials(); + +/// Builds SSL Credentials given SSL specific options +std::shared_ptr SslCredentials( + const SslCredentialsOptions& options); + +/// Builds credentials for use when running in GCE +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleComputeEngineCredentials(); + +/// Constant for maximum auth token lifetime. +constexpr long kMaxAuthTokenLifetimeSecs = 3600; + +/// Builds Service Account JWT Access credentials. +/// json_key is the JSON key string containing the client's private key. +/// token_lifetime_seconds is the lifetime in seconds of each Json Web Token +/// (JWT) created with this credentials. It should not exceed +/// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. +std::shared_ptr ServiceAccountJWTAccessCredentials( + const grpc::string& json_key, + long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + +/// Builds refresh token credentials. +/// json_refresh_token is the JSON string containing the refresh token along +/// with a client_id and client_secret. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleRefreshTokenCredentials( + const grpc::string& json_refresh_token); + +/// Builds access token credentials. +/// access_token is an oauth2 access token that was fetched using an out of band +/// mechanism. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr AccessTokenCredentials( + const grpc::string& access_token); + +/// Builds IAM credentials. +/// +/// \warning Only use these credentials when connecting to a Google endpoint. +/// Using these credentials to connect to any other service may result in this +/// service being able to impersonate your client for requests to Google +/// services. +std::shared_ptr GoogleIAMCredentials( + const grpc::string& authorization_token, + const grpc::string& authority_selector); + +/// Combines a channel credentials and a call credentials into a composite +/// channel credentials. +std::shared_ptr CompositeChannelCredentials( + const std::shared_ptr& channel_creds, + const std::shared_ptr& call_creds); + +/// Combines two call credentials objects into a composite call credentials. +std::shared_ptr CompositeCallCredentials( + const std::shared_ptr& creds1, + const std::shared_ptr& creds2); + +/// Credentials for an unencrypted, unauthenticated channel +std::shared_ptr InsecureChannelCredentials(); + +/// Credentials for a channel using Cronet. +std::shared_ptr CronetChannelCredentials(void* engine); + +/// User defined metadata credentials. +class MetadataCredentialsPlugin { + public: + virtual ~MetadataCredentialsPlugin() {} + + /// If this method returns true, the Process function will be scheduled in + /// a different thread from the one processing the call. + virtual bool IsBlocking() const { return true; } + + /// Type of credentials this plugin is implementing. + virtual const char* GetType() const { return ""; } + + /// Gets the auth metatada produced by this plugin. + /// The fully qualified method name is: + /// service_url + "/" + method_name. + /// The channel_auth_context contains (among other things), the identity of + /// the server. + virtual grpc::Status GetMetadata( + grpc::string_ref service_url, grpc::string_ref method_name, + const grpc::AuthContext& channel_auth_context, + std::multimap* metadata) = 0; +}; + +std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin); + +namespace experimental { + +/// Options used to build AltsCredentials. +struct AltsCredentialsOptions { + /// service accounts of target endpoint that will be acceptable + /// by the client. If service accounts are provided and none of them matches + /// that of the server, authentication will fail. + std::vector target_service_accounts; +}; + +/// Builds ALTS Credentials given ALTS specific options +std::shared_ptr AltsCredentials( + const AltsCredentialsOptions& options); + +/// Builds Local Credentials. +std::shared_ptr LocalCredentials( + grpc_local_connect_type type); + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_SECURITY_CREDENTIALS_H diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index c366693eced..c217dccac9c 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "src/cpp/client/create_channel_internal.h" diff --git a/src/cpp/client/credentials_cc.cc b/src/cpp/client/credentials_cc.cc index 2a0f06f424e..4377be0f2d7 100644 --- a/src/cpp/client/credentials_cc.cc +++ b/src/cpp/client/credentials_cc.cc @@ -19,9 +19,9 @@ #include #include -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; ChannelCredentials::ChannelCredentials() { g_gli_initializer.summon(); } ChannelCredentials::~ChannelCredentials() {} diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 1b0fa6faea9..275c42ab74b 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -21,31 +21,37 @@ #include #include #include +#include #include #include #include "src/cpp/client/create_channel_internal.h" -namespace grpc { +namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: +<<<<<<< HEAD std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { +======= + std::shared_ptr CreateChannel( + const grpc::string& target, const grpc::ChannelArguments& args) override { +>>>>>>> Changes to fold credentials into grpc_impl from grpc return CreateChannelWithInterceptors( target, args, std::vector>()); + grpc::experimental::ClientInterceptorFactoryInterface>>()); } std::shared_ptr CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return grpc::CreateChannelInternal( "", grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), std::move(interceptor_creators)); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index f490f6e6f9a..e91f7e6b477 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -25,9 +25,9 @@ #include "src/cpp/client/create_channel_internal.h" #include "src/cpp/common/secure_auth_context.h" -namespace grpc { +namespace grpc_impl { -static internal::GrpcLibraryInitializer g_gli_initializer; +static grpc::internal::GrpcLibraryInitializer g_gli_initializer; SecureChannelCredentials::SecureChannelCredentials( grpc_channel_credentials* c_creds) : c_creds_(c_creds) { @@ -39,18 +39,18 @@ std::shared_ptr SecureChannelCredentials::CreateChannelImpl( return CreateChannelWithInterceptors( target, args, std::vector< - std::unique_ptr>()); + std::unique_ptr>()); } std::shared_ptr SecureChannelCredentials::CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return CreateChannelInternal( + return grpc::CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, nullptr), @@ -83,14 +83,14 @@ std::shared_ptr WrapCallCredentials( } // namespace std::shared_ptr GoogleDefaultCredentials() { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapChannelCredentials(grpc_google_default_credentials_create()); } // Builds SSL Credentials given SSL specific options std::shared_ptr SslCredentials( const SslCredentialsOptions& options) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; @@ -106,7 +106,7 @@ namespace experimental { // Builds ALTS Credentials given ALTS specific options std::shared_ptr AltsCredentials( const AltsCredentialsOptions& options) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). grpc_alts_credentials_options* c_options = grpc_alts_credentials_client_options_create(); for (auto service_account = options.target_service_accounts.begin(); @@ -123,7 +123,7 @@ std::shared_ptr AltsCredentials( // Builds Local Credentials std::shared_ptr LocalCredentials( grpc_local_connect_type type) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapChannelCredentials(grpc_local_credentials_create(type)); } @@ -131,7 +131,7 @@ std::shared_ptr LocalCredentials( // Builds credentials for use when running in GCE std::shared_ptr GoogleComputeEngineCredentials() { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials( grpc_google_compute_engine_credentials_create(nullptr)); } @@ -139,7 +139,7 @@ std::shared_ptr GoogleComputeEngineCredentials() { // Builds JWT credentials. std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, long token_lifetime_seconds) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). if (token_lifetime_seconds <= 0) { gpr_log(GPR_ERROR, "Trying to create JWTCredentials with non-positive lifetime"); @@ -154,7 +154,7 @@ std::shared_ptr ServiceAccountJWTAccessCredentials( // Builds refresh token credentials. std::shared_ptr GoogleRefreshTokenCredentials( const grpc::string& json_refresh_token) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials(grpc_google_refresh_token_credentials_create( json_refresh_token.c_str(), nullptr)); } @@ -162,7 +162,7 @@ std::shared_ptr GoogleRefreshTokenCredentials( // Builds access token credentials. std::shared_ptr AccessTokenCredentials( const grpc::string& access_token) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials( grpc_access_token_credentials_create(access_token.c_str(), nullptr)); } @@ -171,7 +171,7 @@ std::shared_ptr AccessTokenCredentials( std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector) { - GrpcLibraryCodegen init; // To call grpc_init(). + grpc::GrpcLibraryCodegen init; // To call grpc_init(). return WrapCallCredentials(grpc_google_iam_credentials_create( authorization_token.c_str(), authority_selector.c_str(), nullptr)); } @@ -207,6 +207,23 @@ std::shared_ptr CompositeCallCredentials( return nullptr; } +std::shared_ptr MetadataCredentialsFromPlugin( + std::unique_ptr plugin) { + grpc::GrpcLibraryCodegen init; // To call grpc_init(). + const char* type = plugin->GetType(); + grpc::MetadataCredentialsPluginWrapper* wrapper = + new grpc::MetadataCredentialsPluginWrapper(std::move(plugin)); + grpc_metadata_credentials_plugin c_plugin = { + grpc::MetadataCredentialsPluginWrapper::GetMetadata, + grpc::MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; + return WrapCallCredentials( + grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); +} + +} // namespace grpc_impl + +namespace grpc { + void MetadataCredentialsPluginWrapper::Destroy(void* wrapper) { if (wrapper == nullptr) return; MetadataCredentialsPluginWrapper* w = @@ -308,17 +325,4 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::unique_ptr plugin) : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {} -std::shared_ptr MetadataCredentialsFromPlugin( - std::unique_ptr plugin) { - GrpcLibraryCodegen init; // To call grpc_init(). - const char* type = plugin->GetType(); - MetadataCredentialsPluginWrapper* wrapper = - new MetadataCredentialsPluginWrapper(std::move(plugin)); - grpc_metadata_credentials_plugin c_plugin = { - MetadataCredentialsPluginWrapper::GetMetadata, - MetadataCredentialsPluginWrapper::Destroy, wrapper, type}; - return WrapCallCredentials( - grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); -} - -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index fa2f64ed1d8..4e9f121d2ce 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -27,7 +27,7 @@ #include "src/core/lib/security/credentials/credentials.h" #include "src/cpp/server/thread_pool_interface.h" -namespace grpc { +namespace grpc_impl { class SecureChannelCredentials final : public ChannelCredentials { public: @@ -44,9 +44,9 @@ class SecureChannelCredentials final : public ChannelCredentials { private: std::shared_ptr CreateChannelWithInterceptors( - const string& target, const grpc::ChannelArguments& args, + const grpc::string& target, const grpc::ChannelArguments& args, std::vector< - std::unique_ptr> + std::unique_ptr> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; @@ -66,6 +66,10 @@ class SecureCallCredentials final : public CallCredentials { grpc_call_credentials* const c_creds_; }; +} // namespace grpc_impl + +namespace grpc { + class MetadataCredentialsPluginWrapper final : private GrpcLibraryCodegen { public: static void Destroy(void* wrapper); diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc index 992f3c488f9..2d5c1b47b17 100644 --- a/test/cpp/end2end/client_crash_test.cc +++ b/test/cpp/end2end/client_crash_test.cc @@ -60,7 +60,7 @@ class CrashTest : public ::testing::Test { })); GPR_ASSERT(server_); return grpc::testing::EchoTestService::NewStub( - CreateChannel(addr, InsecureChannelCredentials())); + grpc::CreateChannel(addr, InsecureChannelCredentials())); } void KillServer() { server_.reset(); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 47231058d17..8438d57b643 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -129,7 +129,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {} std::shared_ptr GetCompatibleClientCreds() { - return MetadataCredentialsFromPlugin( + return grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy, @@ -137,7 +137,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { } std::shared_ptr GetIncompatibleClientCreds() { - return MetadataCredentialsFromPlugin( + return grpc::MetadataCredentialsFromPlugin( std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde", @@ -374,7 +374,7 @@ class End2endTest : public ::testing::TestWithParam { proxy_server_ = builder.BuildAndStart(); - channel_ = CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); } stub_ = grpc::testing::EchoTestService::NewStub(channel_); @@ -1277,7 +1277,7 @@ TEST_P(End2endTest, ChannelStateTimeout) { server_address << "127.0.0.1:" << port; // Channel to non-existing server auto channel = - CreateChannel(server_address.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address.str(), InsecureChannelCredentials()); // Start IDLE EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true)); @@ -1826,7 +1826,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kBadMetadataKey, "Does not matter, will fail the key is invalid.", false, true)))); @@ -1844,7 +1844,7 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "With illegal \n value.", false, true)))); @@ -1862,7 +1862,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", false, @@ -1926,7 +1926,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { EchoResponse response; ClientContext context; context.set_credentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", true, @@ -1952,11 +1952,11 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { const char kMetadataVal1[] = "call-creds-val1"; const char kMetadataVal2[] = "call-creds-val2"; - context.set_credentials(CompositeCallCredentials( - MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::CompositeCallCredentials( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, true, true))), - MetadataCredentialsFromPlugin(std::unique_ptr( + grpc::MetadataCredentialsFromPlugin(std::unique_ptr( new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, true, true))))); request.set_message("Hello"); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index ad67402e3df..a1d95644635 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -147,7 +147,7 @@ class FilterEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); ResetConnectionCounter(); ResetCallCounter(); diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 8c4b3cf1fd3..0ea7deb9409 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -91,7 +91,7 @@ class GenericEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index b96ff53a3ea..0b85c62c8c4 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -125,7 +125,7 @@ class HealthServiceEnd2endTest : public ::testing::Test { void ResetStubs() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); hc_stub_ = grpc::health::v1::Health::NewStub(channel); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index b0dd901cf11..dbd078c2d99 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -296,7 +296,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { void ResetStub() { std::shared_ptr channel = inproc_ ? server_->InProcessChannel(ChannelArguments()) - : CreateChannel(server_address_.str(), + : grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -322,7 +322,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { void SendEchoToDupService() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest send_request; EchoResponse recv_response; @@ -374,7 +374,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { void SendSimpleServerStreamingToDupService() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest request; EchoResponse response; diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index 917ca28020a..e25286b8b64 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -245,7 +245,7 @@ class MockTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc index 36dea1fcb31..eb651df21df 100644 --- a/test/cpp/end2end/nonblocking_test.cc +++ b/test/cpp/end2end/nonblocking_test.cc @@ -106,7 +106,7 @@ class NonblockingTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = CreateChannel( + std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), grpc::InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index ff097aa9a77..d817438f41b 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -55,7 +55,7 @@ class ProtoServerReflectionTest : public ::testing::Test { void ResetStub() { string target = "dns:localhost:" + to_string(port_); std::shared_ptr channel = - CreateChannel(target, InsecureChannelCredentials()); + grpc::CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel)); desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); diff --git a/test/cpp/end2end/raw_end2end_test.cc b/test/cpp/end2end/raw_end2end_test.cc index c8556bae954..184dc1e5f56 100644 --- a/test/cpp/end2end/raw_end2end_test.cc +++ b/test/cpp/end2end/raw_end2end_test.cc @@ -130,7 +130,7 @@ class RawEnd2EndTest : public ::testing::Test { void ResetStub() { ChannelArguments args; - std::shared_ptr channel = CreateChannel( + std::shared_ptr channel = grpc::CreateChannel( server_address_.str(), grpc::InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc index d744a93912e..43b00b95f49 100644 --- a/test/cpp/end2end/server_builder_plugin_test.cc +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -185,7 +185,7 @@ class ServerBuilderPluginTest : public ::testing::TestWithParam { void ResetStub() { string target = "dns:localhost:" + to_string(port_); - channel_ = CreateChannel(target, InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc index c47e25052e2..fc3ce097b6f 100644 --- a/test/cpp/end2end/server_early_return_test.cc +++ b/test/cpp/end2end/server_early_return_test.cc @@ -123,7 +123,7 @@ class ServerEarlyReturnTest : public ::testing::Test { server_ = builder.BuildAndStart(); channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index 028191c93c3..db7712b6c99 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -265,7 +265,7 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncUnaryTest, UnaryTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -308,7 +308,7 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeClientStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -317,7 +317,7 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeServerStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -326,7 +326,7 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeBidiStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -356,7 +356,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnaryTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -428,7 +428,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, BidiStreamingTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -509,7 +509,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); GenericStub generic_stub(channel); const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); @@ -612,7 +612,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnimplementedRpcTest) { ChannelArguments args; std::shared_ptr channel = - CreateChannel(server_address, InsecureChannelCredentials()); + grpc::CreateChannel(server_address, InsecureChannelCredentials()); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; @@ -665,7 +665,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) { ChannelArguments args; std::shared_ptr channel = - CreateChannel(server_address, InsecureChannelCredentials()); + grpc::CreateChannel(server_address, InsecureChannelCredentials()); std::unique_ptr stub; stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; diff --git a/test/cpp/end2end/server_load_reporting_end2end_test.cc b/test/cpp/end2end/server_load_reporting_end2end_test.cc index 7bc9af2a6eb..8eba9127ec6 100644 --- a/test/cpp/end2end/server_load_reporting_end2end_test.cc +++ b/test/cpp/end2end/server_load_reporting_end2end_test.cc @@ -94,7 +94,7 @@ class ServerLoadReportingEnd2endTest : public ::testing::Test { const grpc::string& lb_tag, const grpc::string& message, size_t num_requests) { auto stub = EchoTestService::NewStub( - CreateChannel(server_address_, InsecureChannelCredentials())); + grpc::CreateChannel(server_address_, InsecureChannelCredentials())); grpc::string lb_token = lb_id + lb_tag; for (int i = 0; i < num_requests; ++i) { ClientContext ctx; diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index 440656588b2..a604ffdfbd8 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -146,7 +146,7 @@ class End2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 5b8af61ee33..d2eca091149 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -97,7 +97,7 @@ class CommonStressTestInsecure : public CommonStressTest { public: void ResetStub() override { std::shared_ptr channel = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } bool AllowExhaustion() override { return false; } diff --git a/test/cpp/end2end/time_change_test.cc b/test/cpp/end2end/time_change_test.cc index 7f4e3caf6f9..688549e5772 100644 --- a/test/cpp/end2end/time_change_test.cc +++ b/test/cpp/end2end/time_change_test.cc @@ -139,7 +139,7 @@ class TimeChangeTest : public ::testing::Test { "--address=" + addr, })); GPR_ASSERT(server_); - channel_ = CreateChannel(addr, InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(addr, InsecureChannelCredentials()); GPR_ASSERT(channel_); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 181e11f12b2..7d4d5d99446 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -288,7 +288,7 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")", workers[i].c_str(), i); if (!run_inproc) { - servers[i].stub = WorkerService::NewStub(CreateChannel( + servers[i].stub = WorkerService::NewStub(grpc::CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( GetCredType(workers[i], per_worker_credential_types, credential_type), @@ -349,7 +349,7 @@ std::unique_ptr RunScenario( gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", worker.c_str(), i + num_servers); if (!run_inproc) { - clients[i].stub = WorkerService::NewStub(CreateChannel( + clients[i].stub = WorkerService::NewStub(grpc::CreateChannel( worker, GetCredentialsProvider()->GetChannelCredentials( GetCredType(worker, per_worker_credential_types, credential_type), @@ -557,7 +557,7 @@ bool RunQuit( ChannelArguments channel_args; for (size_t i = 0; i < workers.size(); i++) { - auto stub = WorkerService::NewStub(CreateChannel( + auto stub = WorkerService::NewStub(grpc::CreateChannel( workers[i], GetCredentialsProvider()->GetChannelCredentials( GetCredType(workers[i], per_worker_credential_types, credential_type), diff --git a/test/cpp/server/server_request_call_test.cc b/test/cpp/server/server_request_call_test.cc index 9831c061766..14b735cf13d 100644 --- a/test/cpp/server/server_request_call_test.cc +++ b/test/cpp/server/server_request_call_test.cc @@ -115,7 +115,7 @@ TEST(ServerRequestCallTest, ShortDeadlineDoesNotCauseOkayFalse) { }); auto stub = testing::EchoTestService::NewStub( - CreateChannel(address, InsecureChannelCredentials())); + grpc::CreateChannel(address, InsecureChannelCredentials())); for (int i = 0; i < 100; i++) { gpr_log(GPR_INFO, "Sending %d.", i); diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 1d641535e29..525a5be1f33 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -75,7 +75,7 @@ class CliCallTest : public ::testing::Test { void ResetStub() { channel_ = - CreateChannel(server_address_.str(), InsecureChannelCredentials()); + grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index c0b999b511c..5c32198bc3a 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -34,7 +34,7 @@ class SslCredentialProvider : public testing::CredentialTypeProvider { public: std::shared_ptr GetChannelCredentials( grpc::ChannelArguments* args) override { - return SslCredentials(SslCredentialsOptions()); + return grpc::SslCredentials(SslCredentialsOptions()); } std::shared_ptr GetServerCredentials() override { return nullptr; @@ -116,7 +116,7 @@ std::shared_ptr CreateTestChannel( &channel_args); GPR_ASSERT(channel_creds != nullptr); if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); } @@ -157,7 +157,7 @@ std::shared_ptr CreateTestChannel( const grpc::string& connect_to = server.empty() ? override_hostname : server; if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } if (interceptor_creators.empty()) { return ::grpc::CreateCustomChannel(connect_to, channel_creds, @@ -222,7 +222,7 @@ std::shared_ptr CreateTestChannel( &channel_args); GPR_ASSERT(channel_creds != nullptr); if (creds.get()) { - channel_creds = CompositeChannelCredentials(channel_creds, creds); + channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); } return experimental::CreateCustomChannelWithInterceptors( server, channel_creds, channel_args, std::move(interceptor_creators)); diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 57cdbeb7b76..e44ada46c24 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -122,7 +122,7 @@ class TestCliCredentials final : public grpc::testing::CliCredentials { return InsecureChannelCredentials(); } SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - return SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); + return grpc::SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); } const grpc::string GetCredentialUsage() const override { return ""; } diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 49688e5cf9b..455f94e33d4 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -63,7 +63,7 @@ class DefaultCredentialsProvider : public CredentialsProvider { } else if (type == grpc::testing::kTlsCredentialsType) { SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; args->SetSslTargetNameOverride("foo.test.google.fr"); - return SslCredentials(ssl_opts); + return grpc::SslCredentials(ssl_opts); } else if (type == grpc::testing::kGoogleDefaultCredentialsType) { return grpc::GoogleDefaultCredentials(); } else { From 8d2207da4d72d9fbbf4b512484a2458722e45459 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 21 Mar 2019 17:36:19 -0700 Subject: [PATCH 045/112] WIP: New changes to make namespace work --- include/grpcpp/create_channel.h | 5 +++-- include/grpcpp/create_channel_impl.h | 2 +- src/cpp/client/create_channel.cc | 4 ++-- src/cpp/client/create_channel_posix.cc | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index d9d7d432c3f..b9e31a63d39 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -19,6 +19,7 @@ #ifndef GRPCPP_CREATE_CHANNEL_H #define GRPCPP_CREATE_CHANNEL_H +#include #include namespace grpc { @@ -29,9 +30,9 @@ static inline std::shared_ptr CreateChannel( return ::grpc_impl::CreateChannelImpl(target, creds); } -static inline std::shared_ptr CreateCustomChannel( +static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, - const std::shared_ptr& creds, + const std::shared_ptr& creds, const ChannelArguments& args) { return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); } diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 84dd2f7c765..e44a82b1426 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -49,7 +49,7 @@ std::shared_ptr CreateChannelImpl( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelImpl( +std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index c217dccac9c..bafdcec99a1 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -19,9 +19,9 @@ #include #include -#include -#include +#include #include +#include #include #include "src/cpp/client/create_channel_internal.h" diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 6de373577eb..8f74794de79 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "src/cpp/client/create_channel_internal.h" From e57182ab6160a6dbb7f76730b177b55a1e44cfbe Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 22 Mar 2019 14:15:36 -0700 Subject: [PATCH 046/112] Fix the compile errors for tests and namespace. --- include/grpcpp/security/credentials_impl.h | 4 ++-- test/cpp/util/grpc_tool.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 8ec339639b5..a42dbabb155 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -44,7 +44,7 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -78,7 +78,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannel( + friend std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 44b14bf617f..54ac8d2a884 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -217,7 +217,7 @@ std::shared_ptr CreateCliChannel( if (!cred.GetSslTargetNameOverride().empty()) { args.SetSslTargetNameOverride(cred.GetSslTargetNameOverride()); } - return grpc::CreateCustomChannel(server_address, cred.GetCredentials(), args); + return CreateCustomChannel(server_address, cred.GetCredentials(), args); } struct Command { From 60bdeef9f4377d328c62c2b79ecdf3ed0fcdb720 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 22 Mar 2019 15:09:30 -0700 Subject: [PATCH 047/112] Move Channel also to impl for now --- include/grpcpp/create_channel.h | 2 +- include/grpcpp/impl/codegen/client_context.h | 3 +- include/grpcpp/security/credentials.h | 41 +++++++++++-------- include/grpcpp/security/credentials_impl.h | 12 +++--- src/cpp/client/create_channel.cc | 2 +- src/cpp/client/create_channel_posix.cc | 2 +- src/cpp/client/credentials_cc.cc | 2 +- src/cpp/client/insecure_credentials.cc | 11 ++--- src/cpp/client/secure_credentials.cc | 10 ++--- src/cpp/client/secure_credentials.h | 8 ++-- test/cpp/end2end/end2end_test.cc | 33 ++++++++------- test/cpp/end2end/filter_end2end_test.cc | 4 +- test/cpp/end2end/generic_end2end_test.cc | 4 +- .../end2end/health_service_end2end_test.cc | 4 +- test/cpp/end2end/hybrid_end2end_test.cc | 10 ++--- test/cpp/end2end/mock_test.cc | 4 +- test/cpp/end2end/server_early_return_test.cc | 4 +- .../server_interceptors_end2end_test.cc | 21 ++++++---- test/cpp/end2end/streaming_throughput_test.cc | 4 +- test/cpp/end2end/thread_stress_test.cc | 4 +- test/cpp/util/cli_call_test.cc | 4 +- 21 files changed, 102 insertions(+), 87 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index b9e31a63d39..19a73563298 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -19,8 +19,8 @@ #ifndef GRPCPP_CREATE_CHANNEL_H #define GRPCPP_CREATE_CHANNEL_H -#include #include +#include namespace grpc { diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index f5bcdfa5403..7326648b46f 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -309,7 +309,8 @@ class ClientContext { /// call. /// /// \see https://grpc.io/docs/guides/auth.html - void set_credentials(const std::shared_ptr& creds) { + void set_credentials( + const std::shared_ptr& creds) { creds_ = creds; } diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8c99aab6c59..8755d8384e3 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -30,7 +30,8 @@ typedef ::grpc_impl::SslCredentialsOptions SslCredentialsOptions; typedef ::grpc_impl::SecureCallCredentials SecureCallCredentials; typedef ::grpc_impl::SecureChannelCredentials SecureChannelCredentials; -static inline std::shared_ptr GoogleDefaultCredentials() { +static inline std::shared_ptr +GoogleDefaultCredentials() { return ::grpc_impl::GoogleDefaultCredentials(); } @@ -39,30 +40,34 @@ static inline std::shared_ptr SslCredentials( return ::grpc_impl::SslCredentials(options); } -static inline std::shared_ptr GoogleComputeEngineCredentials() { +static inline std::shared_ptr +GoogleComputeEngineCredentials() { return ::grpc_impl::GoogleComputeEngineCredentials(); } -static inline std::shared_ptr ServiceAccountJWTAccessCredentials( +static inline std::shared_ptr +ServiceAccountJWTAccessCredentials( const grpc::string& json_key, long token_lifetime_seconds = ::grpc_impl::kMaxAuthTokenLifetimeSecs) { - return ::grpc_impl::ServiceAccountJWTAccessCredentials(json_key, token_lifetime_seconds); + return ::grpc_impl::ServiceAccountJWTAccessCredentials( + json_key, token_lifetime_seconds); } -static inline std::shared_ptr GoogleRefreshTokenCredentials( - const grpc::string& json_refresh_token) { +static inline std::shared_ptr +GoogleRefreshTokenCredentials(const grpc::string& json_refresh_token) { return ::grpc_impl::GoogleRefreshTokenCredentials(json_refresh_token); } -static inline std::shared_ptr AccessTokenCredentials( - const grpc::string& access_token) { +static inline std::shared_ptr +AccessTokenCredentials(const grpc::string& access_token) { return ::grpc_impl::AccessTokenCredentials(access_token); } static inline std::shared_ptr GoogleIAMCredentials( const grpc::string& authorization_token, const grpc::string& authority_selector) { - return ::grpc_impl::GoogleIAMCredentials(authorization_token, authority_selector); + return ::grpc_impl::GoogleIAMCredentials(authorization_token, + authority_selector); } static inline std::shared_ptr CompositeChannelCredentials( @@ -71,30 +76,34 @@ static inline std::shared_ptr CompositeChannelCredentials( return ::grpc_impl::CompositeChannelCredentials(channel_creds, call_creds); } -static inline std::shared_ptr CompositeCallCredentials( - const std::shared_ptr& creds1, - const std::shared_ptr& creds2) { +static inline std::shared_ptr +CompositeCallCredentials(const std::shared_ptr& creds1, + const std::shared_ptr& creds2) { return ::grpc_impl::CompositeCallCredentials(creds1, creds2); } -static inline std::shared_ptr InsecureChannelCredentials() { +static inline std::shared_ptr +InsecureChannelCredentials() { return ::grpc_impl::InsecureChannelCredentials(); } -static inline std::shared_ptr CronetChannelCredentials(void* engine) { +static inline std::shared_ptr +CronetChannelCredentials(void* engine) { return ::grpc_impl::CronetChannelCredentials(engine); } typedef ::grpc_impl::MetadataCredentialsPlugin MetadataCredentialsPlugin; -static inline std::shared_ptr MetadataCredentialsFromPlugin( +static inline std::shared_ptr +MetadataCredentialsFromPlugin( std::unique_ptr plugin) { return ::grpc_impl::MetadataCredentialsFromPlugin(std::move(plugin)); } namespace experimental { -typedef ::grpc_impl::experimental::AltsCredentialsOptions AltsCredentialsOptions; +typedef ::grpc_impl::experimental::AltsCredentialsOptions + AltsCredentialsOptions; static inline std::shared_ptr AltsCredentials( const AltsCredentialsOptions& options) { diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index a42dbabb155..843b0e2f58e 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -88,19 +88,19 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. virtual std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) { return nullptr; } @@ -280,6 +280,6 @@ std::shared_ptr LocalCredentials( grpc_local_connect_type type); } // namespace experimental -} // namespace grpc +} // namespace grpc_impl #endif // GRPCPP_SECURITY_CREDENTIALS_H diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index bafdcec99a1..ca7038b8893 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -20,8 +20,8 @@ #include #include -#include #include +#include #include #include "src/cpp/client/create_channel_internal.h" diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 8f74794de79..54b7148865b 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -19,8 +19,8 @@ #include #include #include -#include #include +#include #include "src/cpp/client/create_channel_internal.h" diff --git a/src/cpp/client/credentials_cc.cc b/src/cpp/client/credentials_cc.cc index 4377be0f2d7..62334bd9eba 100644 --- a/src/cpp/client/credentials_cc.cc +++ b/src/cpp/client/credentials_cc.cc @@ -30,4 +30,4 @@ CallCredentials::CallCredentials() { g_gli_initializer.summon(); } CallCredentials::~CallCredentials() {} -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 275c42ab74b..3a6b1aa6e05 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,13 +31,8 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: -<<<<<<< HEAD std::shared_ptr CreateChannelImpl( - const string& target, const grpc::ChannelArguments& args) override { -======= - std::shared_ptr CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) override { ->>>>>>> Changes to fold credentials into grpc_impl from grpc return CreateChannelWithInterceptors( target, args, std::vector CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); @@ -66,4 +61,4 @@ std::shared_ptr InsecureChannelCredentials() { new InsecureChannelCredentialsImpl()); } -} // namespace grpc +} // namespace grpc_impl diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index e91f7e6b477..71ad5a73c3b 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -35,11 +35,11 @@ SecureChannelCredentials::SecureChannelCredentials( } std::shared_ptr SecureChannelCredentials::CreateChannelImpl( - const string& target, const grpc::ChannelArguments& args) { + const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, - std::vector< - std::unique_ptr>()); + std::vector>()); } std::shared_ptr @@ -220,7 +220,7 @@ std::shared_ptr MetadataCredentialsFromPlugin( grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr)); } -} // namespace grpc_impl +} // namespace grpc_impl namespace grpc { @@ -325,4 +325,4 @@ MetadataCredentialsPluginWrapper::MetadataCredentialsPluginWrapper( std::unique_ptr plugin) : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {} -} // namespace grpc_impl +} // namespace grpc diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 4e9f121d2ce..1dc083fa0cf 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -38,15 +38,15 @@ class SecureChannelCredentials final : public ChannelCredentials { grpc_channel_credentials* GetRawCreds() { return c_creds_; } std::shared_ptr CreateChannelImpl( - const string& target, const grpc::ChannelArguments& args) override; + const grpc::string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, - std::vector< - std::unique_ptr> + std::vector> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; @@ -66,7 +66,7 @@ class SecureCallCredentials final : public CallCredentials { grpc_call_credentials* const c_creds_; }; -} // namespace grpc_impl +} // namespace grpc_impl namespace grpc { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 8438d57b643..a359701f7ab 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -374,7 +374,8 @@ class End2endTest : public ::testing::TestWithParam { proxy_server_ = builder.BuildAndStart(); - channel_ = grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); + channel_ = + grpc::CreateChannel(proxyaddr.str(), InsecureChannelCredentials()); } stub_ = grpc::testing::EchoTestService::NewStub(channel_); @@ -1825,8 +1826,8 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kBadMetadataKey, "Does not matter, will fail the key is invalid.", false, true)))); @@ -1843,8 +1844,8 @@ TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "With illegal \n value.", false, true)))); @@ -1861,8 +1862,8 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", false, @@ -1925,8 +1926,8 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { EchoRequest request; EchoResponse response; ClientContext context; - context.set_credentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( + context.set_credentials(grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( new TestMetadataCredentialsPlugin( TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", true, @@ -1953,12 +1954,14 @@ TEST_P(SecureEnd2endTest, CompositeCallCreds) { const char kMetadataVal2[] = "call-creds-val2"; context.set_credentials(grpc::CompositeCallCredentials( - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( - new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, true, - true))), - grpc::MetadataCredentialsFromPlugin(std::unique_ptr( - new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, true, - true))))); + grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin(kMetadataKey1, kMetadataVal1, + true, true))), + grpc::MetadataCredentialsFromPlugin( + std::unique_ptr( + new TestMetadataCredentialsPlugin(kMetadataKey2, kMetadataVal2, + true, true))))); request.set_message("Hello"); request.mutable_param()->set_echo_metadata(true); diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc index a1d95644635..a4c981a3eb1 100644 --- a/test/cpp/end2end/filter_end2end_test.cc +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -146,8 +146,8 @@ class FilterEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); ResetConnectionCounter(); ResetCallCounter(); diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 0ea7deb9409..c2807310aa4 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -90,8 +90,8 @@ class GenericEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); generic_stub_.reset(new GenericStub(channel)); } diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 0b85c62c8c4..13d5ea55c15 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -124,8 +124,8 @@ class HealthServiceEnd2endTest : public ::testing::Test { } void ResetStubs() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); hc_stub_ = grpc::health::v1::Health::NewStub(channel); } diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index dbd078c2d99..75001f0ab27 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -297,7 +297,7 @@ class HybridEnd2endTest : public ::testing::TestWithParam { std::shared_ptr channel = inproc_ ? server_->InProcessChannel(ChannelArguments()) : grpc::CreateChannel(server_address_.str(), - InsecureChannelCredentials()); + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } @@ -321,8 +321,8 @@ class HybridEnd2endTest : public ::testing::TestWithParam { } void SendEchoToDupService() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest send_request; EchoResponse recv_response; @@ -373,8 +373,8 @@ class HybridEnd2endTest : public ::testing::TestWithParam { } void SendSimpleServerStreamingToDupService() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); auto stub = grpc::testing::duplicate::EchoTestService::NewStub(channel); EchoRequest request; EchoResponse response; diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index e25286b8b64..0196c9de7e0 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -244,8 +244,8 @@ class MockTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc index fc3ce097b6f..6f35c3e7d93 100644 --- a/test/cpp/end2end/server_early_return_test.cc +++ b/test/cpp/end2end/server_early_return_test.cc @@ -122,8 +122,8 @@ class ServerEarlyReturnTest : public ::testing::Test { builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc index db7712b6c99..68103f7ed34 100644 --- a/test/cpp/end2end/server_interceptors_end2end_test.cc +++ b/test/cpp/end2end/server_interceptors_end2end_test.cc @@ -265,7 +265,8 @@ class ServerInterceptorsEnd2endSyncUnaryTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncUnaryTest, UnaryTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -308,7 +309,8 @@ class ServerInterceptorsEnd2endSyncStreamingTest : public ::testing::Test { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeClientStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -317,7 +319,8 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ClientStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeServerStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -326,7 +329,8 @@ TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, ServerStreamingTest) { TEST_F(ServerInterceptorsEnd2endSyncStreamingTest, BidiStreamingTest) { ChannelArguments args; DummyInterceptor::Reset(); - auto channel = grpc::CreateChannel(server_address_, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address_, InsecureChannelCredentials()); MakeBidiStreamingCall(channel); // Make sure all 20 dummy interceptors were run EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); @@ -356,7 +360,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnaryTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -428,7 +433,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, BidiStreamingTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); auto stub = grpc::testing::EchoTestService::NewStub(channel); EchoRequest send_request; @@ -509,7 +515,8 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) { auto server = builder.BuildAndStart(); ChannelArguments args; - auto channel = grpc::CreateChannel(server_address, InsecureChannelCredentials()); + auto channel = + grpc::CreateChannel(server_address, InsecureChannelCredentials()); GenericStub generic_stub(channel); const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index a604ffdfbd8..0c10957eb77 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -145,8 +145,8 @@ class End2endTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); } diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index d2eca091149..eb8e7958b4b 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -96,8 +96,8 @@ template class CommonStressTestInsecure : public CommonStressTest { public: void ResetStub() override { - std::shared_ptr channel = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + std::shared_ptr channel = grpc::CreateChannel( + server_address_.str(), InsecureChannelCredentials()); this->stub_ = grpc::testing::EchoTestService::NewStub(channel); } bool AllowExhaustion() override { return false; } diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc index 525a5be1f33..a91705bd514 100644 --- a/test/cpp/util/cli_call_test.cc +++ b/test/cpp/util/cli_call_test.cc @@ -74,8 +74,8 @@ class CliCallTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - channel_ = - grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); + channel_ = grpc::CreateChannel(server_address_.str(), + InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } From be9479542c8862d7c92e73e6f1af908f9021b07a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 29 Mar 2019 08:28:55 -0700 Subject: [PATCH 048/112] Fix include header issue --- include/grpcpp/security/credentials_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 843b0e2f58e..49f7293a40a 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -282,4 +282,4 @@ std::shared_ptr LocalCredentials( } // namespace experimental } // namespace grpc_impl -#endif // GRPCPP_SECURITY_CREDENTIALS_H +#endif // GRPCPP_SECURITY_CREDENTIALS_IMPL_H From 2049b6c2bd7021676193ecd5734e86bd257ffe98 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 9 Apr 2019 14:27:23 -0700 Subject: [PATCH 049/112] Fix build errors --- include/grpcpp/security/credentials.h | 1 - include/grpcpp/security/credentials_impl.h | 14 +++++++------- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 8755d8384e3..5eb77096bd0 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -22,7 +22,6 @@ #include namespace grpc { -class Channel; typedef ::grpc_impl::ChannelCredentials ChannelCredentials; typedef ::grpc_impl::CallCredentials CallCredentials; diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 49f7293a40a..a54519f358a 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -34,23 +34,23 @@ struct grpc_call; namespace grpc { class ChannelArguments; -class Channel; } // namespace grpc namespace grpc_impl { +class Channel; class ChannelCredentials; class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr CreateCustomChannelImpl( +std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, @@ -78,12 +78,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannelImpl( + friend std::shared_ptr CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -92,12 +92,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannelImpl( + virtual std::shared_ptr CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr CreateChannelWithInterceptors( + virtual std::shared_ptr CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 3a6b1aa6e05..fca757b66c8 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,7 +31,7 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannelImpl( + std::shared_ptr CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 71ad5a73c3b..df0f48df198 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -34,7 +34,7 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannelImpl( +std::shared_ptr SecureChannelCredentials::CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, From df2c2c114c07c36c9d161395f00f57b612019ccd Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 13:36:04 -0700 Subject: [PATCH 050/112] Fix access to some CreateChannel/CreateCustomChannel methods --- include/grpcpp/create_channel.h | 4 ++-- include/grpcpp/security/credentials_impl.h | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 19a73563298..2d5b85aa819 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -24,7 +24,7 @@ namespace grpc { -static inline std::shared_ptr CreateChannel( +static inline std::shared_ptr<::grpc::Channel> CreateChannel( const grpc::string& target, const std::shared_ptr& creds) { return ::grpc_impl::CreateChannelImpl(target, creds); @@ -39,7 +39,7 @@ static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( namespace experimental { -static inline std::shared_ptr CreateCustomChannelWithInterceptors( +static inline std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index a54519f358a..e233041afc3 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -44,13 +44,13 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr CreateCustomChannel( +std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); namespace experimental { -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args, @@ -78,12 +78,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr CreateCustomChannel( + friend std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); - friend std::shared_ptr + friend std::shared_ptr<::grpc::Channel> grpc_impl::experimental::CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, @@ -92,12 +92,12 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr CreateChannel( + virtual std::shared_ptr<::grpc::Channel> CreateChannel( const grpc::string& target, const grpc::ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is // implemented as a virtual function so that it does not break API. - virtual std::shared_ptr CreateChannelWithInterceptors( + virtual std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> From 5274deb32bc6f8ec064c3ce8ad1e84a067db2652 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 14:11:23 -0700 Subject: [PATCH 051/112] Fix the rebase and build --- include/grpcpp/create_channel.h | 3 ++- include/grpcpp/create_channel_impl.h | 2 +- include/grpcpp/security/credentials_impl.h | 9 +++------ include/grpcpp/support/channel_arguments_impl.h | 5 ++--- src/cpp/client/insecure_credentials.cc | 2 +- src/cpp/client/secure_credentials.cc | 2 +- test/cpp/util/grpc_tool.cc | 3 ++- 7 files changed, 12 insertions(+), 14 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index 2d5b85aa819..e7336cb2adf 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -39,7 +39,8 @@ static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( namespace experimental { -static inline std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( +static inline std::shared_ptr<::grpc::Channel> +CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, const ChannelArguments& args, diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index e44a82b1426..84dd2f7c765 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -49,7 +49,7 @@ std::shared_ptr CreateChannelImpl( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannel( +std::shared_ptr CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index e233041afc3..19017093dd5 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -27,15 +27,12 @@ #include #include #include +#include #include #include struct grpc_call; -namespace grpc { -class ChannelArguments; -} // namespace grpc - namespace grpc_impl { class Channel; @@ -78,7 +75,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { virtual SecureChannelCredentials* AsSecureCredentials() = 0; private: - friend std::shared_ptr<::grpc::Channel> CreateCustomChannel( + friend std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -92,7 +89,7 @@ class ChannelCredentials : private grpc::GrpcLibraryCodegen { grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators); - virtual std::shared_ptr<::grpc::Channel> CreateChannel( + virtual std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) = 0; // This function should have been a pure virtual function, but it is diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index 8276c1d9099..db85e9b07ad 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -31,11 +31,10 @@ namespace grpc { namespace testing { class ChannelArgumentsTest; } // namespace testing - -class SecureChannelCredentials; } // namespace grpc namespace grpc_impl { +class SecureChannelCredentials; /// Options for channel creation. The user can use generic setters to pass /// key value pairs down to C channel creation code. For gRPC related options, @@ -126,7 +125,7 @@ class ChannelArguments { } private: - friend class grpc::SecureChannelCredentials; + friend class grpc_impl::SecureChannelCredentials; friend class grpc::testing::ChannelArgumentsTest; /// Default pointer argument operations. diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index fca757b66c8..3a6b1aa6e05 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,7 +31,7 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index df0f48df198..71ad5a73c3b 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -34,7 +34,7 @@ SecureChannelCredentials::SecureChannelCredentials( g_gli_initializer.summon(); } -std::shared_ptr SecureChannelCredentials::CreateChannel( +std::shared_ptr SecureChannelCredentials::CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) { return CreateChannelWithInterceptors( target, args, diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index 54ac8d2a884..dbac31170f0 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -217,7 +217,8 @@ std::shared_ptr CreateCliChannel( if (!cred.GetSslTargetNameOverride().empty()) { args.SetSslTargetNameOverride(cred.GetSslTargetNameOverride()); } - return CreateCustomChannel(server_address, cred.GetCredentials(), args); + return ::grpc::CreateCustomChannel(server_address, cred.GetCredentials(), + args); } struct Command { From 33722ff1c6840ae8b32f3d82e6ea74a71262eb51 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 23 Apr 2019 15:31:30 -0700 Subject: [PATCH 052/112] Put callback behind a combiner, cancel callbacks in shutdown --- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index 6993edf8a01..e69b824304d 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -31,6 +31,7 @@ #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/combiner.h" namespace grpc_core { @@ -40,7 +41,8 @@ void ares_uv_poll_close_cb(uv_handle_t* handle) { Delete(handle); } class GrpcPolledFdLibuv : public GrpcPolledFd { public: - GrpcPolledFdLibuv(ares_socket_t as) : as_(as) { + GrpcPolledFdLibuv(ares_socket_t as, grpc_combiner* combiner) + : as_(as), combiner_(combiner) { gpr_asprintf(&name_, "c-ares socket: %" PRIdPTR, (intptr_t)as); handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); @@ -72,8 +74,15 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { } void ShutdownLocked(grpc_error* error) override { + grpc_core::ExecCtx exec_ctx; uv_poll_stop(handle_); uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); + if (read_closure_) { + GRPC_CLOSURE_SCHED(read_closure_, GRPC_ERROR_CANCELLED); + } + if (write_closure_) { + GRPC_CLOSURE_SCHED(write_closure_, GRPC_ERROR_CANCELLED); + } } ares_socket_t GetWrappedAresSocketLocked() override { return as_; } @@ -86,13 +95,25 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { grpc_closure* read_closure_ = nullptr; grpc_closure* write_closure_ = nullptr; int poll_events_ = 0; + grpc_combiner* combiner_; }; -void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { - grpc_core::ExecCtx exec_ctx; +struct AresUvPollCbArg { + AresUvPollCbArg(uv_poll_t* handle, int status, int events) + : handle(handle), status(status), events(events) {} + + uv_poll_t* handle; + int status; + int events; +}; + +static void inner_callback(void* arg, grpc_error* error) { + AresUvPollCbArg* arg_struct = reinterpret_cast(arg); + uv_poll_t* handle = arg_struct->handle; + int status = arg_struct->status; + int events = arg_struct->events; GrpcPolledFdLibuv* polled_fd = reinterpret_cast(handle->data); - grpc_error* error = GRPC_ERROR_NONE; if (status < 0) { error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("cares polling error"); error = @@ -110,6 +131,18 @@ void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { polled_fd->poll_events_ &= ~UV_WRITABLE; } uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); + Delete(arg_struct); +} + +void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { + grpc_core::ExecCtx exec_ctx; + GrpcPolledFdLibuv* polled_fd = + reinterpret_cast(handle->data); + AresUvPollCbArg* arg = New(handle, status, events); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_CREATE(inner_callback, arg, + grpc_combiner_scheduler(polled_fd->combiner_)), + GRPC_ERROR_NONE); } class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { @@ -117,7 +150,7 @@ class GrpcPolledFdFactoryLibuv : public GrpcPolledFdFactory { GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as, grpc_pollset_set* driver_pollset_set, grpc_combiner* combiner) override { - return New(as); + return New(as, combiner); } void ConfigureAresChannelLocked(ares_channel channel) override {} From 634cece3f35ed5affc52f1b7a32697949a630d15 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 23 Apr 2019 15:51:53 -0700 Subject: [PATCH 053/112] Fix sanity tests --- .../c_ares/grpc_ares_wrapper_libuv_windows.cc | 2 +- .../c_ares/grpc_ares_wrapper_libuv_windows.h | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc index 837593a62bc..706bc659582 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2016 gRPC authors. + * Copyright 2019 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h index 07c0e37552b..ed40e58f7cc 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h @@ -1,6 +1,26 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_LIBUV_WINDOWS_H +#include + #include #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" From 072fbc44a06490e1220fe3c779475ed02d9295c6 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 23 Apr 2019 16:37:51 -0700 Subject: [PATCH 054/112] Respect interval_us setting for TestServicer --- src/python/grpcio_tests/tests/interop/methods.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 40341ca091b..08d8901a6b4 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -25,6 +25,7 @@ import enum import json import os import threading +import time from google import auth as google_auth from google.auth import environment_vars as google_auth_environment_vars @@ -38,6 +39,7 @@ from src.proto.grpc.testing import test_pb2_grpc _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" +_US_IN_A_SECOND = 1000 * 1000 def _maybe_echo_metadata(servicer_context): @@ -77,6 +79,8 @@ class TestService(test_pb2_grpc.TestServiceServicer): def StreamingOutputCall(self, request, context): _maybe_echo_status_and_message(request, context) for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( type=request.response_type, @@ -95,6 +99,9 @@ class TestService(test_pb2_grpc.TestServiceServicer): for request in request_iterator: _maybe_echo_status_and_message(request, context) for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep( + response_parameters.interval_us / _US_IN_A_SECOND) yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( type=request.payload.type, From 7ee19a0b6b8cb22e9cf3f86af659746d8277cd69 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Tue, 23 Apr 2019 18:14:03 -0700 Subject: [PATCH 055/112] Reviewer comments - mainly make ParsedLoadBalancingConfig refcounted --- .../filters/client_channel/client_channel.cc | 22 ++++----- .../ext/filters/client_channel/lb_policy.h | 4 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 36 +++++++------- .../lb_policy/pick_first/pick_first.cc | 5 +- .../lb_policy/round_robin/round_robin.cc | 5 +- .../client_channel/lb_policy/xds/xds.cc | 48 ++++++++++--------- .../client_channel/lb_policy_factory.h | 2 +- .../client_channel/lb_policy_registry.cc | 2 +- .../client_channel/lb_policy_registry.h | 2 +- .../client_channel/resolver_result_parsing.cc | 8 ++-- .../client_channel/resolver_result_parsing.h | 16 +++---- .../client_channel/resolving_lb_policy.cc | 9 ++-- .../client_channel/resolving_lb_policy.h | 16 +++---- .../filters/client_channel/service_config.cc | 1 + .../ext/filters/client_channel/subchannel.cc | 1 - 15 files changed, 90 insertions(+), 87 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 99ffeeaa522..2f13ca7e438 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -224,7 +224,7 @@ class ChannelData { static bool ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config); + RefCountedPtr* lb_policy_config); grpc_error* DoPingLocked(grpc_transport_op* op); @@ -263,6 +263,7 @@ class ChannelData { OrphanablePtr resolving_lb_policy_; grpc_connectivity_state_tracker state_tracker_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; + const char* health_check_service_name_ = nullptr; // // Fields accessed from both data plane and control plane combiners. @@ -934,16 +935,11 @@ class ChannelData::ClientChannelControlHelper Subchannel* CreateSubchannel(const grpc_channel_args& args) override { grpc_arg args_to_add[2]; int num_args_to_add = 0; - if (chand_->service_config_ != nullptr) { - const auto* health_check_object = static_cast( - chand_->service_config_->GetParsedGlobalServiceConfigObject( - HealthCheckParser::ParserIndex())); - if (health_check_object != nullptr) { - args_to_add[0] = grpc_channel_arg_string_create( - const_cast("grpc.temp.health_check"), - const_cast(health_check_object->service_name())); - num_args_to_add++; - } + if (chand_->health_check_service_name_ != nullptr) { + args_to_add[0] = grpc_channel_arg_string_create( + const_cast("grpc.temp.health_check"), + const_cast(chand_->health_check_service_name_)); + num_args_to_add++; } args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( chand_->subchannel_pool_.get()); @@ -1121,7 +1117,7 @@ ChannelData::~ChannelData() { // resolver result update. bool ChannelData::ProcessResolverResultLocked( void* arg, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config) { + RefCountedPtr* lb_policy_config) { ChannelData* chand = static_cast(arg); ProcessedResolverResult resolver_result(result); const char* service_config_json = resolver_result.service_config_json(); @@ -1149,6 +1145,8 @@ bool ChannelData::ProcessResolverResultLocked( // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_config = resolver_result.lb_policy_config(); + chand->health_check_service_name_ = + resolver_result.health_check_service_name(); return service_config_changed; } diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h index b23f77bee7c..88b7ad35b9b 100644 --- a/src/core/ext/filters/client_channel/lb_policy.h +++ b/src/core/ext/filters/client_channel/lb_policy.h @@ -38,7 +38,7 @@ namespace grpc_core { /// Interface for parsed forms of load balancing configs found in a service /// config. -class ParsedLoadBalancingConfig { +class ParsedLoadBalancingConfig : public RefCounted { public: virtual ~ParsedLoadBalancingConfig() = default; @@ -209,7 +209,7 @@ class LoadBalancingPolicy : public InternallyRefCounted { /// config are available. struct UpdateArgs { ServerAddressList addresses; - const ParsedLoadBalancingConfig* config = nullptr; + RefCountedPtr config; const grpc_channel_args* args = nullptr; // TODO(roth): Remove everything below once channel args is diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index ba7276747fd..9580583aff1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -120,16 +120,16 @@ constexpr char kGrpclb[] = "grpclb"; class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { public: - ParsedGrpcLbConfig(UniquePtr child_policy) + ParsedGrpcLbConfig(RefCountedPtr child_policy) : child_policy_(std::move(child_policy)) {} const char* name() const override { return kGrpclb; } - const ParsedLoadBalancingConfig* child_policy() const { - return child_policy_.get(); + RefCountedPtr child_policy() const { + return child_policy_; } private: - UniquePtr child_policy_; + RefCountedPtr child_policy_; }; class GrpcLb : public LoadBalancingPolicy { @@ -316,7 +316,6 @@ class GrpcLb : public LoadBalancingPolicy { // Helper functions used in UpdateLocked(). void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses, const grpc_channel_args& args); - void ParseLbConfig(const ParsedGrpcLbConfig* grpclb_config); static void OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error); void CancelBalancerChannelConnectivityWatchLocked(); @@ -394,7 +393,7 @@ class GrpcLb : public LoadBalancingPolicy { // until it reports READY, at which point it will be moved to child_policy_. OrphanablePtr pending_child_policy_; // The child policy config. - const ParsedLoadBalancingConfig* child_policy_config_ = nullptr; + RefCountedPtr child_policy_config_ = nullptr; // Child policy in state READY. bool child_policy_ready_ = false; }; @@ -1387,7 +1386,14 @@ void GrpcLb::FillChildRefsForChannelz( void GrpcLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_channel_ == nullptr; - ParseLbConfig(static_cast(args.config)); + auto* grpclb_config = + static_cast(args.config.get()); + if (grpclb_config != nullptr) { + child_policy_config_ = grpclb_config->child_policy(); + } else { + child_policy_config_ = nullptr; + } + ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); @@ -1476,14 +1482,6 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked( response_generator_->SetResponse(std::move(result)); } -void GrpcLb::ParseLbConfig(const ParsedGrpcLbConfig* grpclb_config) { - if (grpclb_config != nullptr) { - child_policy_config_ = grpclb_config->child_policy(); - } else { - child_policy_config_ = nullptr; - } -} - void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg, grpc_error* error) { GrpcLb* self = static_cast(arg); @@ -1806,15 +1804,15 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kGrpclb; } - UniquePtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (json == nullptr) { - return UniquePtr( + return RefCountedPtr( New(nullptr)); } InlinedVector error_list; - UniquePtr child_policy = nullptr; + RefCountedPtr child_policy = nullptr; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { @@ -1834,7 +1832,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { } } if (error_list.empty()) { - return UniquePtr( + return RefCountedPtr( New(std::move(child_policy))); } else { *error = diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index 398c8efd524..95f6a149720 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -544,12 +544,13 @@ class PickFirstFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kPickFirst; } - UniquePtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { if (json != nullptr) { GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); } - return UniquePtr(New()); + return RefCountedPtr( + New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc index 089f57827c7..2d4ecd38f96 100644 --- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc @@ -521,12 +521,13 @@ class RoundRobinFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kRoundRobin; } - UniquePtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { if (json != nullptr) { GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); } - return UniquePtr(New()); + return RefCountedPtr( + New()); } }; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index ce752adaeef..e496a666931 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -122,8 +122,8 @@ constexpr char kDefaultLocalityName[] = "xds_default_locality"; class ParsedXdsConfig : public ParsedLoadBalancingConfig { public: ParsedXdsConfig(const char* balancer_name, - UniquePtr child_policy, - UniquePtr fallback_policy) + RefCountedPtr child_policy, + RefCountedPtr fallback_policy) : balancer_name_(balancer_name), child_policy_(std::move(child_policy)), fallback_policy_(std::move(fallback_policy)) {} @@ -132,18 +132,18 @@ class ParsedXdsConfig : public ParsedLoadBalancingConfig { const char* balancer_name() const { return balancer_name_; }; - const ParsedLoadBalancingConfig* child_policy() const { - return child_policy_.get(); + RefCountedPtr child_policy() const { + return child_policy_; } - const ParsedLoadBalancingConfig* fallback_policy() const { - return fallback_policy_.get(); + RefCountedPtr fallback_policy() const { + return fallback_policy_; } private: const char* balancer_name_ = nullptr; - UniquePtr child_policy_; - UniquePtr fallback_policy_; + RefCountedPtr child_policy_; + RefCountedPtr fallback_policy_; }; class XdsLb : public LoadBalancingPolicy { @@ -308,9 +308,10 @@ class XdsLb : public LoadBalancingPolicy { : parent_(std::move(parent)) {} ~LocalityEntry() = default; - void UpdateLocked(xds_grpclb_serverlist* serverlist, - const ParsedLoadBalancingConfig* child_policy_config, - const grpc_channel_args* args); + void UpdateLocked( + xds_grpclb_serverlist* serverlist, + RefCountedPtr child_policy_config, + const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -352,9 +353,10 @@ class XdsLb : public LoadBalancingPolicy { RefCountedPtr parent_; }; - void UpdateLocked(const LocalityList& locality_list, - const ParsedLoadBalancingConfig* child_policy_config, - const grpc_channel_args* args, XdsLb* parent); + void UpdateLocked( + const LocalityList& locality_list, + RefCountedPtr child_policy_config, + const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -426,7 +428,7 @@ class XdsLb : public LoadBalancingPolicy { // Timeout in milliseconds for before using fallback backend addresses. // 0 means not using fallback. - const ParsedLoadBalancingConfig* fallback_policy_config_ = nullptr; + RefCountedPtr fallback_policy_config_; int lb_fallback_timeout_ms_ = 0; // The backend addresses from the resolver. UniquePtr fallback_backend_addresses_; @@ -436,7 +438,7 @@ class XdsLb : public LoadBalancingPolicy { grpc_closure lb_on_fallback_; // The policy to use for the backends. - const ParsedLoadBalancingConfig* child_policy_config_ = nullptr; + RefCountedPtr child_policy_config_; // Map of policies to use in the backend LocalityMap locality_map_; LocalityList locality_serverlist_; @@ -1241,7 +1243,7 @@ void XdsLb::ParseLbConfig(const ParsedXdsConfig* xds_config) { void XdsLb::UpdateLocked(UpdateArgs args) { const bool is_initial_update = lb_chand_ == nullptr; - ParseLbConfig(static_cast(args.config)); + ParseLbConfig(static_cast(args.config.get())); // TODO(juanlishen): Pass fallback policy config update after fallback policy // is added. if (balancer_name_ == nullptr) { @@ -1311,7 +1313,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - const ParsedLoadBalancingConfig* child_policy_config, + RefCountedPtr child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1404,7 +1406,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - const ParsedLoadBalancingConfig* child_policy_config, + RefCountedPtr child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // This should never be invoked if we do not have serverlist_, as fallback @@ -1661,7 +1663,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { const char* name() const override { return kXds; } - UniquePtr ParseLoadBalancingConfig( + RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const override { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (json == nullptr) { @@ -1677,8 +1679,8 @@ class XdsFactory : public LoadBalancingPolicyFactory { InlinedVector error_list; const char* balancer_name = nullptr; - UniquePtr child_policy = nullptr; - UniquePtr fallback_policy = nullptr; + RefCountedPtr child_policy = nullptr; + RefCountedPtr fallback_policy = nullptr; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; @@ -1727,7 +1729,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { "field:balancerName error:not found")); } if (error_list.empty()) { - return UniquePtr(New( + return RefCountedPtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { *error = ServiceConfig::CreateErrorFromVector("Xds Parser", &error_list); diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h index 4aee5848c86..aaf3e959542 100644 --- a/src/core/ext/filters/client_channel/lb_policy_factory.h +++ b/src/core/ext/filters/client_channel/lb_policy_factory.h @@ -37,7 +37,7 @@ class LoadBalancingPolicyFactory { /// Caller does NOT take ownership of result. virtual const char* name() const GRPC_ABSTRACT; - virtual UniquePtr ParseLoadBalancingConfig( + virtual RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error) const GRPC_ABSTRACT; virtual ~LoadBalancingPolicyFactory() {} diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index 78b8a6f706f..310d41078f7 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -163,7 +163,7 @@ grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, } } // namespace -UniquePtr +RefCountedPtr LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index ffeb44de9de..298d73a6312 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -54,7 +54,7 @@ class LoadBalancingPolicyRegistry { /// Returns a parsed object of the load balancing policy to be used from a /// LoadBalancingConfig array \a json. \a field_name specifies - static UniquePtr ParseLoadBalancingConfig( + static RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error); /// Validates if the deprecated loadBalancingPolicy field can be parsed. diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index e4a36119c3f..36192a5929e 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -80,9 +80,11 @@ ProcessedResolverResult::ProcessedResolverResult( void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result) { if (service_config_ == nullptr) return; - health_check_ = static_cast( + auto* health_check = static_cast( service_config_->GetParsedGlobalServiceConfigObject( HealthCheckParser::ParserIndex())); + health_check_service_name_ = + health_check != nullptr ? health_check->service_name() : nullptr; service_config_json_ = service_config_->service_config_json(); auto* parsed_object = static_cast( service_config_->GetParsedGlobalServiceConfigObject( @@ -113,7 +115,7 @@ void ProcessedResolverResult::ProcessLbPolicy( service_config_->GetParsedGlobalServiceConfigObject( ClientChannelServiceConfigParser::ParserIndex())); if (parsed_object != nullptr) { - if (parsed_object->parsed_lb_config()) { + if (parsed_object->parsed_lb_config() != nullptr) { lb_policy_name_.reset( gpr_strdup(parsed_object->parsed_lb_config()->name())); lb_policy_config_ = parsed_object->parsed_lb_config(); @@ -339,7 +341,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; - UniquePtr parsed_lb_config; + RefCountedPtr parsed_lb_config; const char* lb_policy_name = nullptr; Optional retry_throttling; for (grpc_json* field = json->child; field != nullptr; field = field->next) { diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 0369e0b704f..097f1e39e62 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -45,7 +45,7 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { }; ClientChannelGlobalParsedObject( - UniquePtr parsed_lb_config, + RefCountedPtr parsed_lb_config, const char* parsed_deprecated_lb_policy, const Optional& retry_throttling) : parsed_lb_config_(std::move(parsed_lb_config)), @@ -56,8 +56,8 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { return retry_throttling_; } - const ParsedLoadBalancingConfig* parsed_lb_config() const { - return parsed_lb_config_.get(); + RefCountedPtr parsed_lb_config() const { + return parsed_lb_config_; } const char* parsed_deprecated_lb_policy() const { @@ -65,7 +65,7 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { } private: - UniquePtr parsed_lb_config_; + RefCountedPtr parsed_lb_config_; const char* parsed_deprecated_lb_policy_ = nullptr; Optional retry_throttling_; }; @@ -126,11 +126,11 @@ class ProcessedResolverResult { } UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } - const ParsedLoadBalancingConfig* lb_policy_config() { + RefCountedPtr lb_policy_config() { return lb_policy_config_; } - const HealthCheckParsedObject* health_check() { return health_check_; } + const char* health_check_service_name() { return health_check_service_name_; } RefCountedPtr service_config() { return service_config_; } private: @@ -155,10 +155,10 @@ class ProcessedResolverResult { RefCountedPtr service_config_; // LB policy. UniquePtr lb_policy_name_; - const ParsedLoadBalancingConfig* lb_policy_config_ = nullptr; + RefCountedPtr lb_policy_config_ = nullptr; // Retry throttle data. RefCountedPtr retry_throttle_data_; - const HealthCheckParsedObject* health_check_ = nullptr; + const char* health_check_service_name_ = nullptr; }; } // namespace internal diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 34a58358716..79d8cf43bc9 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -184,7 +184,8 @@ class ResolvingLoadBalancingPolicy::ResolvingControlHelper ResolvingLoadBalancingPolicy::ResolvingLoadBalancingPolicy( Args args, TraceFlag* tracer, UniquePtr target_uri, UniquePtr child_policy_name, - const ParsedLoadBalancingConfig* child_lb_config, grpc_error** error) + RefCountedPtr child_lb_config, + grpc_error** error) : LoadBalancingPolicy(std::move(args)), tracer_(tracer), target_uri_(std::move(target_uri)), @@ -332,8 +333,8 @@ void ResolvingLoadBalancingPolicy::OnResolverError(grpc_error* error) { void ResolvingLoadBalancingPolicy::CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, - const ParsedLoadBalancingConfig* lb_policy_config, Resolver::Result result, - TraceStringVector* trace_strings) { + RefCountedPtr lb_policy_config, + Resolver::Result result, TraceStringVector* trace_strings) { // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -529,7 +530,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const bool resolution_contains_addresses = result.addresses.size() > 0; // Process the resolver result. const char* lb_policy_name = nullptr; - const ParsedLoadBalancingConfig* lb_policy_config = nullptr; + RefCountedPtr lb_policy_config = nullptr; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { service_config_changed = diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index 85fad3093e0..9822c2d1dc2 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -54,11 +54,11 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { public: // If error is set when this returns, then construction failed, and // the caller may not use the new object. - ResolvingLoadBalancingPolicy(Args args, TraceFlag* tracer, - UniquePtr target_uri, - UniquePtr child_policy_name, - const ParsedLoadBalancingConfig* child_lb_config, - grpc_error** error); + ResolvingLoadBalancingPolicy( + Args args, TraceFlag* tracer, UniquePtr target_uri, + UniquePtr child_policy_name, + RefCountedPtr child_lb_config, + grpc_error** error); // Private ctor, to be used by client_channel only! // @@ -68,7 +68,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { typedef bool (*ProcessResolverResultCallback)( void* user_data, const Resolver::Result& result, const char** lb_policy_name, - const ParsedLoadBalancingConfig** lb_policy_config); + RefCountedPtr* lb_policy_config); // If error is set when this returns, then construction failed, and // the caller may not use the new object. ResolvingLoadBalancingPolicy( @@ -106,7 +106,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { void OnResolverError(grpc_error* error); void CreateOrUpdateLbPolicyLocked( const char* lb_policy_name, - const ParsedLoadBalancingConfig* lb_policy_config, + RefCountedPtr lb_policy_config, Resolver::Result result, TraceStringVector* trace_strings); OrphanablePtr CreateLbPolicyLocked( const char* lb_policy_name, const grpc_channel_args& args, @@ -123,7 +123,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - const ParsedLoadBalancingConfig* child_lb_config_ = nullptr; + RefCountedPtr child_lb_config_ = nullptr; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index c6c6af35a68..9c2fb254db8 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -78,6 +78,7 @@ ServiceConfig::ServiceConfig(UniquePtr service_config_json, error_list[error_count++] = local_error; } if (error_count > 0) { + gpr_log(GPR_ERROR, "got errors"); *error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Service config parsing error", error_list, error_count); GRPC_ERROR_UNREF(global_error); diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index e7f22b07ae9..639d0ec79f4 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -567,7 +567,6 @@ Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector, health_check_service_name_ = UniquePtr(gpr_strdup(grpc_channel_arg_get_string( grpc_channel_args_find(args_, "grpc.temp.health_check")))); - gpr_log(GPR_ERROR, "healthcheck %s", health_check_service_name_.get()); const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ); const bool channelz_enabled = grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT); From 02cfba7737a50556b256bf9061ec76cb649e71f0 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 18:20:10 -0700 Subject: [PATCH 056/112] Fix make errors --- src/cpp/client/cronet_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index b2801764f20..903f72ffbf0 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -29,7 +29,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { public: CronetChannelCredentialsImpl(void* engine) : engine_(engine) {} - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, From 360251f196cd6900a135674ec9217e705c7a4511 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 23 Apr 2019 18:23:16 -0700 Subject: [PATCH 057/112] Fix make errors --- src/cpp/client/cronet_credentials.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index b2801764f20..903f72ffbf0 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -29,7 +29,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { public: CronetChannelCredentialsImpl(void* engine) : engine_(engine) {} - std::shared_ptr CreateChannel( + std::shared_ptr CreateChannelImpl( const string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, From 81ba5a7b9bd7631d33ad46d1ed73dd7809d3e519 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 24 Apr 2019 08:22:56 -0700 Subject: [PATCH 058/112] Add missing files for build --- BUILD.gn | 1 + CMakeLists.txt | 3 +++ Makefile | 3 +++ build.yaml | 1 + gRPC-C++.podspec | 1 + tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 8 files changed, 13 insertions(+) diff --git a/BUILD.gn b/BUILD.gn index 10b514f8f2e..32e05b32cfd 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1098,6 +1098,7 @@ config("grpc_config") { "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index ee8712f1d38..d103fcec6b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3050,6 +3050,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h @@ -3654,6 +3655,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h @@ -4633,6 +4635,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h diff --git a/Makefile b/Makefile index c7fbca51225..7fe29fbb542 100644 --- a/Makefile +++ b/Makefile @@ -5386,6 +5386,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ @@ -5998,6 +5999,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ @@ -6926,6 +6928,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ diff --git a/build.yaml b/build.yaml index 4593be986bf..f504f4d564b 100644 --- a/build.yaml +++ b/build.yaml @@ -1392,6 +1392,7 @@ filegroups: - include/grpcpp/support/async_unary_call.h - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h + - include/grpcpp/support/channel_arguments_impl.h - include/grpcpp/support/client_callback.h - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 74f758e6487..634b8c181ca 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -128,6 +128,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/async_unary_call.h', 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', + 'include/grpcpp/support/channel_arguments_impl.h', 'include/grpcpp/support/client_callback.h', 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index a0a6e952409..519a112bc2b 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1019,6 +1019,7 @@ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c48c15bd1f5..2fd53b48780 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1021,6 +1021,7 @@ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index bd6d68bc5c3..f1ccacef562 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10178,6 +10178,7 @@ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", @@ -10298,6 +10299,7 @@ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", From a1493cfa626d81c4a9c5e5e79b859f41011b641d Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 24 Apr 2019 08:22:56 -0700 Subject: [PATCH 059/112] Add missing files for build --- BUILD.gn | 1 + CMakeLists.txt | 3 +++ Makefile | 3 +++ build.yaml | 1 + gRPC-C++.podspec | 1 + test/cpp/end2end/message_allocator_end2end_test.cc | 2 +- tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 9 files changed, 14 insertions(+), 1 deletion(-) diff --git a/BUILD.gn b/BUILD.gn index 10b0f1a7fdd..2518db149d7 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1099,6 +1099,7 @@ config("grpc_config") { "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 0edd7fd54ee..3479d17ad06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3051,6 +3051,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h @@ -3657,6 +3658,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h @@ -4640,6 +4642,7 @@ foreach(_hdr include/grpcpp/support/async_unary_call.h include/grpcpp/support/byte_buffer.h include/grpcpp/support/channel_arguments.h + include/grpcpp/support/channel_arguments_impl.h include/grpcpp/support/client_callback.h include/grpcpp/support/client_interceptor.h include/grpcpp/support/config.h diff --git a/Makefile b/Makefile index 57530500b15..5d10bd9f4b7 100644 --- a/Makefile +++ b/Makefile @@ -5391,6 +5391,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ @@ -6005,6 +6006,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ @@ -6937,6 +6939,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ + include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ diff --git a/build.yaml b/build.yaml index 80519946295..f7d2e8be0e9 100644 --- a/build.yaml +++ b/build.yaml @@ -1393,6 +1393,7 @@ filegroups: - include/grpcpp/support/async_unary_call.h - include/grpcpp/support/byte_buffer.h - include/grpcpp/support/channel_arguments.h + - include/grpcpp/support/channel_arguments_impl.h - include/grpcpp/support/client_callback.h - include/grpcpp/support/client_interceptor.h - include/grpcpp/support/config.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index de1bb0ae57f..3141ecdbe17 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -128,6 +128,7 @@ Pod::Spec.new do |s| 'include/grpcpp/support/async_unary_call.h', 'include/grpcpp/support/byte_buffer.h', 'include/grpcpp/support/channel_arguments.h', + 'include/grpcpp/support/channel_arguments_impl.h', 'include/grpcpp/support/client_callback.h', 'include/grpcpp/support/client_interceptor.h', 'include/grpcpp/support/config.h', diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc index 55f792aa3bf..19246e25505 100644 --- a/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -154,7 +154,7 @@ class MessageAllocatorEnd2endTestBase switch (GetParam().protocol) { case Protocol::TCP: channel_ = - CreateCustomChannel(server_address_.str(), channel_creds, args); + ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); break; case Protocol::INPROC: channel_ = server_->InProcessChannel(args); diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 6902c3aa38b..2a71e73a839 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1020,6 +1020,7 @@ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index ed0974fdb2b..438cd023166 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1022,6 +1022,7 @@ include/grpcpp/support/async_stream.h \ include/grpcpp/support/async_unary_call.h \ include/grpcpp/support/byte_buffer.h \ include/grpcpp/support/channel_arguments.h \ +include/grpcpp/support/channel_arguments_impl.h \ include/grpcpp/support/client_callback.h \ include/grpcpp/support/client_interceptor.h \ include/grpcpp/support/config.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9b9ad7d430c..4e5f268b38f 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10198,6 +10198,7 @@ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", @@ -10319,6 +10320,7 @@ "include/grpcpp/support/async_unary_call.h", "include/grpcpp/support/byte_buffer.h", "include/grpcpp/support/channel_arguments.h", + "include/grpcpp/support/channel_arguments_impl.h", "include/grpcpp/support/client_callback.h", "include/grpcpp/support/client_interceptor.h", "include/grpcpp/support/config.h", From 2fa5759d7992b394947eb72812b7e88be74630e0 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 24 Apr 2019 09:41:18 -0700 Subject: [PATCH 060/112] Fix missing include in windows file --- .../resolver/dns/c_ares/grpc_ares_wrapper_windows.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc index f3adc417793..60398c6aedd 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc @@ -25,6 +25,7 @@ #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" +#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" From 4d5a4115570776fb82c96df79e6e66483c63777f Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 24 Apr 2019 09:58:47 -0700 Subject: [PATCH 061/112] Fix clang errors --- test/cpp/end2end/message_allocator_end2end_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/end2end/message_allocator_end2end_test.cc b/test/cpp/end2end/message_allocator_end2end_test.cc index 19246e25505..c833a4ff1b6 100644 --- a/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/test/cpp/end2end/message_allocator_end2end_test.cc @@ -153,8 +153,8 @@ class MessageAllocatorEnd2endTestBase GetParam().credentials_type, &args); switch (GetParam().protocol) { case Protocol::TCP: - channel_ = - ::grpc::CreateCustomChannel(server_address_.str(), channel_creds, args); + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); break; case Protocol::INPROC: channel_ = server_->InProcessChannel(args); From 7fc86bd62f26f6ba74c21e7828c0d648dc501af6 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Wed, 24 Apr 2019 10:40:41 -0700 Subject: [PATCH 062/112] Fix make errors --- src/cpp/client/cronet_credentials.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 903f72ffbf0..89ae9e7e9ce 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -55,10 +55,11 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { } void* engine_; }; - -std::shared_ptr CronetChannelCredentials(void* engine) { +} // namespace grpc +namespace grpc_impl { +std::shared_ptr CronetChannelCredentials( + void* engine) { return std::shared_ptr( - new CronetChannelCredentialsImpl(engine)); + new grpc::CronetChannelCredentialsImpl(engine)); } - -} // namespace grpc +} // namespace grpc_impl From a2316142b237e120f4ac370e608746fb4a440f1a Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 24 Apr 2019 15:29:46 -0700 Subject: [PATCH 063/112] Reviewer comments --- .../filters/client_channel/client_channel.cc | 29 ++- .../client_channel/client_channel_factory.h | 1 - .../health/health_check_parser.cc | 32 ++- .../health/health_check_parser.h | 8 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 5 +- .../client_channel/lb_policy/xds/xds.cc | 6 +- .../client_channel/lb_policy_registry.cc | 12 +- .../client_channel/lb_policy_registry.h | 7 +- .../client_channel/resolver_result_parsing.cc | 109 ++++----- .../client_channel/resolver_result_parsing.h | 42 ++-- .../filters/client_channel/service_config.cc | 5 +- .../filters/client_channel/service_config.h | 66 +++--- .../ext/filters/client_channel/subchannel.h | 1 - .../message_size/message_size_filter.cc | 6 +- .../message_size/message_size_filter.h | 6 +- .../client_channel/service_config_test.cc | 208 +++++++----------- test/cpp/microbenchmarks/bm_call_create.cc | 1 - 17 files changed, 260 insertions(+), 284 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 2f13ca7e438..de5a12a4d91 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -762,11 +762,13 @@ class ChannelData::ConnectivityStateAndPickerSetter { class ChannelData::ServiceConfigSetter { public: ServiceConfigSetter( - ChannelData* chand, - RefCountedPtr retry_throttle_data, + ChannelData* chand, UniquePtr server_name, + Optional + retry_throttle_data, RefCountedPtr service_config) : chand_(chand), - retry_throttle_data_(std::move(retry_throttle_data)), + server_name_(std::move(server_name)), + retry_throttle_data_(retry_throttle_data), service_config_(std::move(service_config)) { GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter"); GRPC_CLOSURE_INIT(&closure_, SetServiceConfigData, this, @@ -780,7 +782,13 @@ class ChannelData::ServiceConfigSetter { ChannelData* chand = self->chand_; // Update channel state. chand->received_service_config_data_ = true; - chand->retry_throttle_data_ = std::move(self->retry_throttle_data_); + if (self->retry_throttle_data_.has_value()) { + chand->retry_throttle_data_ = + internal::ServerRetryThrottleMap::GetDataForServer( + self->server_name_.get(), + self->retry_throttle_data_.value().max_milli_tokens, + self->retry_throttle_data_.value().milli_token_ratio); + } chand->service_config_ = std::move(self->service_config_); // Apply service config to queued picks. for (QueuedPick* pick = chand->queued_picks_; pick != nullptr; @@ -795,7 +803,9 @@ class ChannelData::ServiceConfigSetter { } ChannelData* chand_; - RefCountedPtr retry_throttle_data_; + UniquePtr server_name_; + Optional + retry_throttle_data_; RefCountedPtr service_config_; grpc_closure closure_; }; @@ -1120,15 +1130,16 @@ bool ChannelData::ProcessResolverResultLocked( RefCountedPtr* lb_policy_config) { ChannelData* chand = static_cast(arg); ProcessedResolverResult resolver_result(result); - const char* service_config_json = resolver_result.service_config_json(); + char* service_config_json = gpr_strdup(resolver_result.service_config_json()); if (grpc_client_channel_routing_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json); } // Create service config setter to update channel state in the data // plane combiner. Destroys itself when done. - New(chand, resolver_result.retry_throttle_data(), - resolver_result.service_config()); + New( + chand, UniquePtr(gpr_strdup(resolver_result.server_name())), + resolver_result.retry_throttle_data(), resolver_result.service_config()); // Swap out the data used by GetChannelInfo(). bool service_config_changed; { @@ -1140,7 +1151,7 @@ bool ChannelData::ProcessResolverResultLocked( (service_config_json != nullptr && strcmp(service_config_json, chand->info_service_config_json_.get()) != 0); - chand->info_service_config_json_.reset(gpr_strdup(service_config_json)); + chand->info_service_config_json_.reset(service_config_json); } // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); diff --git a/src/core/ext/filters/client_channel/client_channel_factory.h b/src/core/ext/filters/client_channel/client_channel_factory.h index 883409fbee8..21f78a833df 100644 --- a/src/core/ext/filters/client_channel/client_channel_factory.h +++ b/src/core/ext/filters/client_channel/client_channel_factory.h @@ -23,7 +23,6 @@ #include -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/subchannel.h" #include "src/core/lib/gprpp/abstract.h" diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc index 13bad49c5b6..7760e22b686 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ b/src/core/ext/filters/client_channel/health/health_check_parser.cc @@ -25,12 +25,14 @@ namespace { size_t g_health_check_parser_index; } -UniquePtr HealthCheckParser::ParseGlobalParams( +UniquePtr HealthCheckParser::ParseGlobalParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); const char* service_name = nullptr; + InlinedVector error_list; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) { + GPR_DEBUG_ASSERT(false); continue; } if (strcmp(field->key, "healthCheckConfig") == 0) { @@ -42,33 +44,39 @@ UniquePtr HealthCheckParser::ParseGlobalParams( for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) { + GPR_DEBUG_ASSERT(false); continue; } if (strcmp(sub_field->key, "serviceName") == 0) { if (service_name != nullptr) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:healthCheckConfig field:serviceName error:Duplicate " - "entry"); - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:Duplicate " + "entry")); + continue; } if (sub_field->type != GRPC_JSON_STRING) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:healthCheckConfig error:should be of type string"); - return nullptr; + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:should be of type string")); + continue; } service_name = sub_field->value; } } } } - if (service_name == nullptr) return nullptr; - return UniquePtr( - New(service_name)); + if (error_list.empty()) { + if (service_name == nullptr) return nullptr; + return UniquePtr( + New(service_name)); + } + *error = ServiceConfig::CreateErrorFromVector("field:healthCheckConfig", + &error_list); + return nullptr; } void HealthCheckParser::Register() { g_health_check_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); + UniquePtr(New())); } size_t HealthCheckParser::ParserIndex() { return g_health_check_parser_index; } diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h index 8ab1ba9425d..036cafc68b7 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.h +++ b/src/core/ext/filters/client_channel/health/health_check_parser.h @@ -25,20 +25,22 @@ namespace grpc_core { -class HealthCheckParsedObject : public ServiceConfigParsedObject { +class HealthCheckParsedObject : public ServiceConfig::ParsedConfig { public: HealthCheckParsedObject(const char* service_name) : service_name_(service_name) {} + // Returns the service_name found in the health check config. The lifetime of + // the string is tied to the lifetime of the ServiceConfig object. const char* service_name() const { return service_name_; } private: const char* service_name_; }; -class HealthCheckParser : public ServiceConfigParser { +class HealthCheckParser : public ServiceConfig::Parser { public: - UniquePtr ParseGlobalParams( + UniquePtr ParseGlobalParams( const grpc_json* json, grpc_error** error) override; static void Register(); diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 9580583aff1..c61d6a71527 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -393,7 +393,7 @@ class GrpcLb : public LoadBalancingPolicy { // until it reports READY, at which point it will be moved to child_policy_. OrphanablePtr pending_child_policy_; // The child policy config. - RefCountedPtr child_policy_config_ = nullptr; + RefCountedPtr child_policy_config_; // Child policy in state READY. bool child_policy_ready_ = false; }; @@ -1812,8 +1812,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { New(nullptr)); } InlinedVector error_list; - RefCountedPtr child_policy = nullptr; - + RefCountedPtr child_policy; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index e496a666931..775f45f71b1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1668,11 +1668,11 @@ class XdsFactory : public LoadBalancingPolicyFactory { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); if (json == nullptr) { // xds was mentioned as a policy in the deprecated loadBalancingPolicy - // field. + // field or in the client API. *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Xds Parser has required field - " - "balancerName. Please use loadBalancingConfig instead of the " - "deprecated loadBalancingPolicy"); + "balancerName. Please use loadBalancingConfig field of service " + "config instead."); return nullptr; } GPR_DEBUG_ASSERT(strcmp(json->key, name()) == 0); diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index 310d41078f7..b9ea97d4051 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -189,15 +189,11 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, } } -grpc_error* LoadBalancingPolicyRegistry::ParseDeprecatedLoadBalancingPolicy( - const grpc_json* json) { +grpc_error* LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( + const char* lb_policy_name) { GPR_DEBUG_ASSERT(g_state != nullptr); - GPR_DEBUG_ASSERT(json != nullptr); - if (json->type != GRPC_JSON_STRING) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:type should be string"); - } - auto* factory = g_state->GetLoadBalancingPolicyFactory(json->value); + gpr_log(GPR_ERROR, "%s", lb_policy_name); + auto* factory = g_state->GetLoadBalancingPolicyFactory(lb_policy_name); if (factory == nullptr) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy"); diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 298d73a6312..7fa52914cd9 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -53,13 +53,12 @@ class LoadBalancingPolicyRegistry { static bool LoadBalancingPolicyExists(const char* name); /// Returns a parsed object of the load balancing policy to be used from a - /// LoadBalancingConfig array \a json. \a field_name specifies + /// LoadBalancingConfig array \a json. static RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error); - /// Validates if the deprecated loadBalancingPolicy field can be parsed. - /// Returns GRPC_ERROR_NONE if successfully parsed. - static grpc_error* ParseDeprecatedLoadBalancingPolicy(const grpc_json* json); + /// Validates if a load balancing policy can be created from \a lb_policy_name + static grpc_error* CanCreateLoadBalancingPolicy(const char* lb_policy_name); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 36192a5929e..e868cd70bc6 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -29,6 +29,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" @@ -53,8 +54,9 @@ size_t ClientChannelServiceConfigParser::ParserIndex() { } void ClientChannelServiceConfigParser::Register() { - g_client_channel_service_config_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); + g_client_channel_service_config_parser_index = + ServiceConfig::RegisterParser(UniquePtr( + New())); } ProcessedResolverResult::ProcessedResolverResult( @@ -73,60 +75,57 @@ ProcessedResolverResult::ProcessedResolverResult( } } // Process service config. - ProcessServiceConfig(resolver_result); - ProcessLbPolicy(resolver_result); + const ClientChannelGlobalParsedObject* parsed_object = nullptr; + if (service_config_ != nullptr) { + parsed_object = static_cast( + service_config_->GetParsedGlobalServiceConfigObject( + ClientChannelServiceConfigParser::ParserIndex())); + ProcessServiceConfig(resolver_result, parsed_object); + } + ProcessLbPolicy(resolver_result, parsed_object); } void ProcessedResolverResult::ProcessServiceConfig( - const Resolver::Result& resolver_result) { - if (service_config_ == nullptr) return; + const Resolver::Result& resolver_result, + const ClientChannelGlobalParsedObject* parsed_object) { auto* health_check = static_cast( service_config_->GetParsedGlobalServiceConfigObject( HealthCheckParser::ParserIndex())); health_check_service_name_ = health_check != nullptr ? health_check->service_name() : nullptr; service_config_json_ = service_config_->service_config_json(); - auto* parsed_object = static_cast( - service_config_->GetParsedGlobalServiceConfigObject( - ClientChannelServiceConfigParser::ParserIndex())); if (!parsed_object) { return; } - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); - const char* server_uri = grpc_channel_arg_get_string(channel_arg); - GPR_ASSERT(server_uri != nullptr); - grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); if (parsed_object->retry_throttling().has_value()) { - char* server_name = uri->path[0] == '/' ? uri->path + 1 : uri->path; - retry_throttle_data_ = internal::ServerRetryThrottleMap::GetDataForServer( - server_name, parsed_object->retry_throttling().value().max_milli_tokens, - parsed_object->retry_throttling().value().milli_token_ratio); + const grpc_arg* channel_arg = + grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); + const char* server_uri = grpc_channel_arg_get_string(channel_arg); + GPR_ASSERT(server_uri != nullptr); + grpc_uri* uri = grpc_uri_parse(server_uri, true); + GPR_ASSERT(uri->path[0] != '\0'); + server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; + retry_throttle_data_ = parsed_object->retry_throttling(); + grpc_uri_destroy(uri); } - grpc_uri_destroy(uri); } void ProcessedResolverResult::ProcessLbPolicy( - const Resolver::Result& resolver_result) { + const Resolver::Result& resolver_result, + const ClientChannelGlobalParsedObject* parsed_object) { // Prefer the LB policy name found in the service config. - if (service_config_ != nullptr) { - auto* parsed_object = static_cast( - service_config_->GetParsedGlobalServiceConfigObject( - ClientChannelServiceConfigParser::ParserIndex())); - if (parsed_object != nullptr) { - if (parsed_object->parsed_lb_config() != nullptr) { - lb_policy_name_.reset( - gpr_strdup(parsed_object->parsed_lb_config()->name())); - lb_policy_config_ = parsed_object->parsed_lb_config(); - } else { - lb_policy_name_.reset( - gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); - } + if (parsed_object != nullptr) { + if (parsed_object->parsed_lb_config() != nullptr) { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_lb_config()->name())); + lb_policy_config_ = parsed_object->parsed_lb_config(); + } else { + lb_policy_name_.reset( + gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); + if (lb_policy_name_ != nullptr) { + char* lb_policy_name = lb_policy_name_.get(); + for (size_t i = 0; i < strlen(lb_policy_name); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); } } } @@ -226,7 +225,7 @@ UniquePtr ParseRetryPolicy( retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value); if (retry_policy->max_attempts <= 1) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:maxAttempts error:should be atleast 2")); + "field:maxAttempts error:should be at least 2")); continue; } if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) { @@ -336,13 +335,13 @@ UniquePtr ParseRetryPolicy( } // namespace -UniquePtr +UniquePtr ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; RefCountedPtr parsed_lb_config; - const char* lb_policy_name = nullptr; + UniquePtr lb_policy_name; Optional retry_throttling; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) { @@ -368,21 +367,28 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, if (lb_policy_name != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Duplicate entry")); + continue; } else if (field->type != GRPC_JSON_STRING) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:type should be string")); - } else if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( - field->value)) { + continue; + } + lb_policy_name.reset(gpr_strdup(field->value)); + char* lb_policy = lb_policy_name.get(); + if (lb_policy != nullptr) { + for (size_t i = 0; i < strlen(lb_policy); ++i) { + lb_policy[i] = tolower(lb_policy[i]); + } + } + if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(lb_policy)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); } else { grpc_error* parsing_error = - LoadBalancingPolicyRegistry::ParseDeprecatedLoadBalancingPolicy( - field); + LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( + lb_policy); if (parsing_error != GRPC_ERROR_NONE) { error_list.push_back(parsing_error); - } else { - lb_policy_name = field->value; } } } @@ -490,14 +496,15 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, *error = ServiceConfig::CreateErrorFromVector("Client channel global parser", &error_list); if (*error == GRPC_ERROR_NONE) { - return UniquePtr( + return UniquePtr( New(std::move(parsed_lb_config), - lb_policy_name, retry_throttling)); + std::move(lb_policy_name), + retry_throttling)); } return nullptr; } -UniquePtr +UniquePtr ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); @@ -547,7 +554,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, *error = ServiceConfig::CreateErrorFromVector("Client channel parser", &error_list); if (*error == GRPC_ERROR_NONE) { - return UniquePtr( + return UniquePtr( New(timeout, wait_for_ready, std::move(retry_policy))); } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 097f1e39e62..25830dd4642 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -37,19 +37,19 @@ namespace grpc_core { namespace internal { -class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { +class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { public: struct RetryThrottling { - int max_milli_tokens = 0; - int milli_token_ratio = 0; + intptr_t max_milli_tokens = 0; + intptr_t milli_token_ratio = 0; }; ClientChannelGlobalParsedObject( RefCountedPtr parsed_lb_config, - const char* parsed_deprecated_lb_policy, + UniquePtr parsed_deprecated_lb_policy, const Optional& retry_throttling) : parsed_lb_config_(std::move(parsed_lb_config)), - parsed_deprecated_lb_policy_(parsed_deprecated_lb_policy), + parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)), retry_throttling_(retry_throttling) {} Optional retry_throttling() const { @@ -61,16 +61,16 @@ class ClientChannelGlobalParsedObject : public ServiceConfigParsedObject { } const char* parsed_deprecated_lb_policy() const { - return parsed_deprecated_lb_policy_; + return parsed_deprecated_lb_policy_.get(); } private: RefCountedPtr parsed_lb_config_; - const char* parsed_deprecated_lb_policy_ = nullptr; + UniquePtr parsed_deprecated_lb_policy_; Optional retry_throttling_; }; -class ClientChannelMethodParsedObject : public ServiceConfigParsedObject { +class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { public: struct RetryPolicy { int max_attempts = 0; @@ -99,12 +99,12 @@ class ClientChannelMethodParsedObject : public ServiceConfigParsedObject { UniquePtr retry_policy_; }; -class ClientChannelServiceConfigParser : public ServiceConfigParser { +class ClientChannelServiceConfigParser : public ServiceConfig::Parser { public: - UniquePtr ParseGlobalParams( + UniquePtr ParseGlobalParams( const grpc_json* json, grpc_error** error) override; - UniquePtr ParsePerMethodParams( + UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override; static size_t ParserIndex(); @@ -121,8 +121,12 @@ class ProcessedResolverResult { // Getters. Any managed object's ownership is transferred. const char* service_config_json() { return service_config_json_; } - RefCountedPtr retry_throttle_data() { - return std::move(retry_throttle_data_); + + const char* server_name() { return server_name_; } + + Optional + retry_throttle_data() { + return retry_throttle_data_; } UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } @@ -131,15 +135,19 @@ class ProcessedResolverResult { } const char* health_check_service_name() { return health_check_service_name_; } + RefCountedPtr service_config() { return service_config_; } private: // Finds the service config; extracts LB config and (maybe) retry throttle // params from it. - void ProcessServiceConfig(const Resolver::Result& resolver_result); + void ProcessServiceConfig( + const Resolver::Result& resolver_result, + const ClientChannelGlobalParsedObject* parsed_object); // Extracts the LB policy. - void ProcessLbPolicy(const Resolver::Result& resolver_result); + void ProcessLbPolicy(const Resolver::Result& resolver_result, + const ClientChannelGlobalParsedObject* parsed_object); // Parses the service config. Intended to be used by // ServiceConfig::ParseGlobalParams. @@ -157,7 +165,9 @@ class ProcessedResolverResult { UniquePtr lb_policy_name_; RefCountedPtr lb_policy_config_ = nullptr; // Retry throttle data. - RefCountedPtr retry_throttle_data_; + const char* server_name_ = nullptr; + Optional + retry_throttle_data_; const char* health_check_service_name_ = nullptr; }; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 9c2fb254db8..8db3df712e6 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -34,7 +34,7 @@ namespace grpc_core { namespace { -typedef InlinedVector, +typedef InlinedVector, ServiceConfig::kNumPreallocatedParsers> ServiceConfigParserList; ServiceConfigParserList* g_registered_parsers; @@ -78,7 +78,6 @@ ServiceConfig::ServiceConfig(UniquePtr service_config_json, error_list[error_count++] = local_error; } if (error_count > 0) { - gpr_log(GPR_ERROR, "got errors"); *error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( "Service config parsing error", error_list, error_count); GRPC_ERROR_UNREF(global_error); @@ -314,7 +313,7 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { return *value; } -size_t ServiceConfig::RegisterParser(UniquePtr parser) { +size_t ServiceConfig::RegisterParser(UniquePtr parser) { g_registered_parsers->push_back(std::move(parser)); return g_registered_parsers->size() - 1; } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 85a49855f96..1372b50eb2a 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -55,39 +55,39 @@ namespace grpc_core { -/// This is the base class that all service config parsers MUST use to store -/// parsed service config data. -class ServiceConfigParsedObject { +class ServiceConfig : public RefCounted { public: - virtual ~ServiceConfigParsedObject() = default; + /// This is the base class that all service config parsers MUST use to store + /// parsed service config data. + class ParsedConfig { + public: + virtual ~ParsedConfig() = default; - GRPC_ABSTRACT_BASE_CLASS; -}; + GRPC_ABSTRACT_BASE_CLASS; + }; -/// This is the base class that all service config parsers should derive from. -class ServiceConfigParser { - public: - virtual ~ServiceConfigParser() = default; + /// This is the base class that all service config parsers should derive from. + class Parser { + public: + virtual ~Parser() = default; - virtual UniquePtr ParseGlobalParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr); - return nullptr; - } + virtual UniquePtr ParseGlobalParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr); + return nullptr; + } - virtual UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr); - return nullptr; - } + virtual UniquePtr ParsePerMethodParams( + const grpc_json* json, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr); + return nullptr; + } - GRPC_ABSTRACT_BASE_CLASS; -}; + GRPC_ABSTRACT_BASE_CLASS; + }; -class ServiceConfig : public RefCounted { - public: static constexpr int kNumPreallocatedParsers = 4; - typedef InlinedVector, + typedef InlinedVector, kNumPreallocatedParsers> ServiceConfigObjectsVector; @@ -104,7 +104,7 @@ class ServiceConfig : public RefCounted { RefCountedPtr service_config() { return service_config_; } - ServiceConfigParsedObject* GetMethodParsedObject(int index) const { + ServiceConfig::ParsedConfig* GetMethodParsedObject(int index) const { return method_params_vector_ != nullptr ? (*method_params_vector_)[index].get() : nullptr; @@ -127,14 +127,18 @@ class ServiceConfig : public RefCounted { const char* service_config_json() const { return service_config_json_.get(); } - /// Retrieves the parsed global service config object at index \a index. - ServiceConfigParsedObject* GetParsedGlobalServiceConfigObject(size_t index) { + /// Retrieves the parsed global service config object at index \a index. The + /// lifetime of the returned object is tied to the lifetime of the + /// ServiceConfig object. + ServiceConfig::ParsedConfig* GetParsedGlobalServiceConfigObject( + size_t index) { GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); return parsed_global_service_config_objects_[index].get(); } /// Retrieves the vector of method service config objects for a given path \a - /// path. + /// path. The lifetime of the returned vector and contained objects is tied to + /// the lifetime of the ServiceConfig object. const ServiceConfigObjectsVector* GetMethodServiceConfigObjectsVector( const grpc_slice& path); @@ -144,7 +148,7 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static size_t RegisterParser(UniquePtr parser); + static size_t RegisterParser(UniquePtr parser); static void Init(); @@ -199,7 +203,7 @@ class ServiceConfig : public RefCounted { UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; - InlinedVector, kNumPreallocatedParsers> + InlinedVector, kNumPreallocatedParsers> parsed_global_service_config_objects_; // A map from the method name to the service config objects vector. Note that // we are using a raw pointer and not a unique pointer so that we can use the diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index c67b51a8fa4..9c2e57d3e05 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -23,7 +23,6 @@ #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/connector.h" -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/subchannel_pool_interface.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_stack.h" diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index e19accbe8a7..2014855e5d1 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -44,7 +44,7 @@ size_t g_message_size_parser_index; namespace grpc_core { -UniquePtr MessageSizeParser::ParsePerMethodParams( +UniquePtr MessageSizeParser::ParsePerMethodParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); int max_request_message_bytes = -1; @@ -89,13 +89,13 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( &error_list); return nullptr; } - return UniquePtr(New( + return UniquePtr(New( max_request_message_bytes, max_response_message_bytes)); } void MessageSizeParser::Register() { g_message_size_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); + UniquePtr(New())); } size_t MessageSizeParser::ParserIndex() { return g_message_size_parser_index; } diff --git a/src/core/ext/filters/message_size/message_size_filter.h b/src/core/ext/filters/message_size/message_size_filter.h index e43d7be61b5..cab8bd9627f 100644 --- a/src/core/ext/filters/message_size/message_size_filter.h +++ b/src/core/ext/filters/message_size/message_size_filter.h @@ -26,7 +26,7 @@ extern const grpc_channel_filter grpc_message_size_filter; namespace grpc_core { -class MessageSizeParsedObject : public ServiceConfigParsedObject { +class MessageSizeParsedObject : public ServiceConfig::ParsedConfig { public: struct message_size_limits { int max_send_size; @@ -44,9 +44,9 @@ class MessageSizeParsedObject : public ServiceConfigParsedObject { message_size_limits limits_; }; -class MessageSizeParser : public ServiceConfigParser { +class MessageSizeParser : public ServiceConfig::Parser { public: - UniquePtr ParsePerMethodParams( + UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override; static void Register(); diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 544d91ec02e..fd5304c17d4 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -24,7 +24,7 @@ #include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" -#include "src/core/ext/filters/message_size/message_size_parser.h" +#include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/lib/gpr/string.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" @@ -32,7 +32,7 @@ namespace grpc_core { namespace testing { -class TestParsedObject1 : public ServiceConfigParsedObject { +class TestParsedObject1 : public ServiceConfig::ParsedConfig { public: TestParsedObject1(int value) : value_(value) {} @@ -42,9 +42,9 @@ class TestParsedObject1 : public ServiceConfigParsedObject { int value_; }; -class TestParser1 : public ServiceConfigParser { +class TestParser1 : public ServiceConfig::Parser { public: - UniquePtr ParseGlobalParams( + UniquePtr ParseGlobalParams( const grpc_json* json, grpc_error** error) override { GPR_DEBUG_ASSERT(error != nullptr); for (grpc_json* field = json->child; field != nullptr; @@ -61,7 +61,7 @@ class TestParser1 : public ServiceConfigParser { GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); return nullptr; } - return UniquePtr( + return UniquePtr( New(value)); } } @@ -77,9 +77,9 @@ class TestParser1 : public ServiceConfigParser { } }; -class TestParser2 : public ServiceConfigParser { +class TestParser2 : public ServiceConfig::Parser { public: - UniquePtr ParsePerMethodParams( + UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override { GPR_DEBUG_ASSERT(error != nullptr); for (grpc_json* field = json->child; field != nullptr; @@ -99,7 +99,7 @@ class TestParser2 : public ServiceConfigParser { GRPC_ERROR_CREATE_FROM_STATIC_STRING(InvalidValueErrorMessage()); return nullptr; } - return UniquePtr( + return UniquePtr( New(value)); } } @@ -116,16 +116,16 @@ class TestParser2 : public ServiceConfigParser { }; // This parser always adds errors -class ErrorParser : public ServiceConfigParser { +class ErrorParser : public ServiceConfig::Parser { public: - UniquePtr ParsePerMethodParams( + UniquePtr ParsePerMethodParams( const grpc_json* json, grpc_error** error) override { GPR_DEBUG_ASSERT(error != nullptr); *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(MethodError()); return nullptr; } - UniquePtr ParseGlobalParams( + UniquePtr ParseGlobalParams( const grpc_json* json, grpc_error** error) override { GPR_DEBUG_ASSERT(error != nullptr); *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(GlobalError()); @@ -137,15 +137,22 @@ class ErrorParser : public ServiceConfigParser { static const char* GlobalError() { return "ErrorParser : globalError"; } }; +void VerifyRegexMatch(grpc_error* error, std::regex e) { + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + class ServiceConfigTest : public ::testing::Test { protected: void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); EXPECT_TRUE(ServiceConfig::RegisterParser( - UniquePtr(New())) == 0); + UniquePtr(New())) == 0); EXPECT_TRUE(ServiceConfig::RegisterParser( - UniquePtr(New())) == 1); + UniquePtr(New())) == 1); } }; @@ -156,10 +163,7 @@ TEST_F(ServiceConfigTest, ErrorCheck1) { gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); std::regex e(std::string("failed to parse JSON for service config")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ServiceConfigTest, BasicTest1) { @@ -181,10 +185,7 @@ TEST_F(ServiceConfigTest, ErrorNoNames) { "Params)(.*)(referenced_errors)(.*)(No names " "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " "names specified)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { @@ -200,10 +201,7 @@ TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { "Params)(.*)(referenced_errors)(.*)(No names " "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)(No " "names specified)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ServiceConfigTest, ValidMethodConfig) { @@ -247,10 +245,7 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { "error)(.*)(referenced_errors)(.*)(Global " "Params)(.*)(referenced_errors)(.*)") + TestParser1::InvalidTypeErrorMessage()); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { @@ -263,10 +258,7 @@ TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { "error)(.*)(referenced_errors)(.*)(Global " "Params)(.*)(referenced_errors)(.*)") + TestParser1::InvalidValueErrorMessage()); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ServiceConfigTest, Parser2BasicTest) { @@ -296,10 +288,7 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { "Params)(.*)(referenced_errors)(.*)(methodConfig)(" ".*)(referenced_errors)(.*)") + TestParser2::InvalidTypeErrorMessage()); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { @@ -315,10 +304,7 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { "Params)(.*)(referenced_errors)()(.*)(methodConfig)(" ".*)(referenced_errors)(.*)") + TestParser2::InvalidValueErrorMessage()); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } // Test parsing with ErrorParsers which always add errors @@ -328,9 +314,9 @@ class ErroredParsersScopingTest : public ::testing::Test { ServiceConfig::Shutdown(); ServiceConfig::Init(); EXPECT_TRUE(ServiceConfig::RegisterParser( - UniquePtr(New())) == 0); + UniquePtr(New())) == 0); EXPECT_TRUE(ServiceConfig::RegisterParser( - UniquePtr(New())) == 1); + UniquePtr(New())) == 1); } }; @@ -345,10 +331,7 @@ TEST_F(ErroredParsersScopingTest, GlobalParams) { "Params)(.*)(referenced_errors)()(.*)") + ErrorParser::GlobalError() + std::string("(.*)") + ErrorParser::GlobalError()); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ErroredParsersScopingTest, MethodParams) { @@ -369,10 +352,7 @@ TEST_F(ErroredParsersScopingTest, MethodParams) { "found)(.*)(methodConfig)(.*)(referenced_errors)(.*)") + ErrorParser::MethodError() + std::string("(.*)") + ErrorParser::MethodError() + std::string("(.*)(No names specified)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } class ClientChannelParserTest : public ::testing::Test { @@ -381,7 +361,7 @@ class ClientChannelParserTest : public ::testing::Test { ServiceConfig::Shutdown(); ServiceConfig::Init(); EXPECT_TRUE( - ServiceConfig::RegisterParser(UniquePtr( + ServiceConfig::RegisterParser(UniquePtr( New())) == 0); } @@ -395,7 +375,7 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) { const auto* parsed_object = static_cast( svc_cfg->GetParsedGlobalServiceConfigObject(0)); - const auto* lb_config = parsed_object->parsed_lb_config(); + auto lb_config = parsed_object->parsed_lb_config(); EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); } @@ -405,10 +385,10 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); ASSERT_TRUE(error == GRPC_ERROR_NONE); - const auto* parsed_object = + auto parsed_object = static_cast( svc_cfg->GetParsedGlobalServiceConfigObject(0)); - const auto* lb_config = parsed_object->parsed_lb_config(); + auto lb_config = parsed_object->parsed_lb_config(); EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); } @@ -422,7 +402,7 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { const auto* parsed_object = static_cast( svc_cfg->GetParsedGlobalServiceConfigObject(0)); - const auto* lb_config = parsed_object->parsed_lb_config(); + auto lb_config = parsed_object->parsed_lb_config(); EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); } @@ -441,7 +421,7 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { const auto* parsed_object = static_cast( svc_cfg->GetParsedGlobalServiceConfigObject(0)); - const auto* lb_config = parsed_object->parsed_lb_config(); + auto lb_config = parsed_object->parsed_lb_config(); EXPECT_TRUE(strcmp(lb_config->name(), "xds_experimental") == 0); } @@ -457,13 +437,10 @@ TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) { "Params)(.*)(referenced_errors)(.*)(Client channel global " "parser)(.*)(referenced_errors)(.*)(field:" "loadBalancingConfig error:No known policy)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } -TEST_F(ClientChannelParserTest, InvalidgRPCLbLoadBalancingConfig) { +TEST_F(ClientChannelParserTest, InvalidGrpclbLoadBalancingConfig) { const char* test_json = "{\"loadBalancingConfig\": " "[{\"grpclb\":{\"childPolicy\":[{\"unknown\":{}}]}}]}"; @@ -478,10 +455,7 @@ TEST_F(ClientChannelParserTest, InvalidgRPCLbLoadBalancingConfig) { "parser)(.*)(referenced_errors)(.*)(GrpcLb " "Parser)(.*)(referenced_errors)(.*)(field:childPolicy " "error:No known policy)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InalidLoadBalancingConfigXds) { @@ -503,10 +477,7 @@ TEST_F(ClientChannelParserTest, InalidLoadBalancingConfigXds) { "parser)(.*)(referenced_errors)(.*)(Xds " "Parser)(.*)(referenced_errors)(.*)(field:balancerName " "error:not found)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { @@ -522,6 +493,20 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); } +TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicyAllCaps) { + const char* test_json = "{\"loadBalancingPolicy\":\"PICK_FIRST\"}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + const auto* lb_policy = parsed_object->parsed_deprecated_lb_policy(); + ASSERT_TRUE(lb_policy != nullptr); + EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); +} + TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}"; grpc_error* error = GRPC_ERROR_NONE; @@ -534,10 +519,7 @@ TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { "Params)(.*)(referenced_errors)(.*)(Client channel global " "parser)(.*)(referenced_errors)(.*)(field:" "loadBalancingPolicy error:Unknown lb policy)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { @@ -552,11 +534,8 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { "Params)(.*)(referenced_errors)(.*)(Client channel global " "parser)(.*)(referenced_errors)(.*)(field:loadBalancingPolicy error:Xds " "Parser has required field - balancerName. Please use " - "loadBalancingConfig instead of the deprecated loadBalancingPolicy)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + "loadBalancingConfig field of service config instead.)")); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, ValidRetryThrottling) { @@ -597,10 +576,7 @@ TEST_F(ClientChannelParserTest, RetryThrottlingMissingFields) { "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " "field:maxTokens error:Not found)(.*)(field:retryThrottling " "field:tokenRatio error:Not found)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { @@ -621,10 +597,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { "Params)(.*)(referenced_errors)(.*)(Client channel global " "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " "field:maxTokens error:should be greater than zero)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { @@ -645,10 +618,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { "Params)(.*)(referenced_errors)(.*)(Client channel global " "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " "field:tokenRatio error:Failed parsing)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, ValidTimeout) { @@ -695,10 +665,7 @@ TEST_F(ClientChannelParserTest, InvalidTimeout) { "referenced_errors)(.*)(Client channel " "parser)(.*)(referenced_errors)(.*)(field:timeout " "error:Failed parsing)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, ValidWaitForReady) { @@ -751,10 +718,7 @@ TEST_F(ClientChannelParserTest, InvalidWaitForReady) { "referenced_errors)(.*)(Client channel " "parser)(.*)(referenced_errors)(.*)(field:waitForReady " "error:Type should be true/false)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, ValidRetryPolicy) { @@ -818,11 +782,8 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxAttempts) { "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" ".*)(Client channel " "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:maxAttempts error:should be atleast 2)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + "*)(field:maxAttempts error:should be at least 2)")); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { @@ -852,10 +813,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { ".*)(Client channel " "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." "*)(field:initialBackoff error:Failed to parse)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { @@ -885,10 +843,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { ".*)(Client channel " "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." "*)(field:maxBackoff error:failed to parse)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { @@ -918,10 +873,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { ".*)(Client channel " "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." "*)(field:backoffMultiplier error:should be of type number)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { @@ -951,10 +903,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { ".*)(Client channel " "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." "*)(field:retryableStatusCodes error:should be non-empty)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } class MessageSizeParserTest : public ::testing::Test { @@ -962,7 +911,7 @@ class MessageSizeParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( New())) == 0); } }; @@ -1013,10 +962,7 @@ TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) { "referenced_errors)(.*)(Message size " "parser)(.*)(referenced_errors)(.*)(field:" "maxRequestMessageBytes error:should be non-negative)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { @@ -1040,10 +986,7 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { "referenced_errors)(.*)(Message size " "parser)(.*)(referenced_errors)(.*)(field:" "maxResponseMessageBytes error:should be of type number)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); + VerifyRegexMatch(error, e); } class HealthCheckParserTest : public ::testing::Test { @@ -1051,7 +994,7 @@ class HealthCheckParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( + EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( New())) == 0); } }; @@ -1090,8 +1033,9 @@ TEST_F(HealthCheckParserTest, MultipleEntries) { std::regex e( std::string("(Service config parsing " "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig " - "field:serviceName error:Duplicate entry)")); + "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig)(" + ".*)(referenced_errors)(.*)" + "(field:serviceName error:Duplicate entry)")); std::smatch match; std::string s(grpc_error_string(error)); EXPECT_TRUE(std::regex_search(s, match, e)); diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 177b0187cc6..e84999b213f 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -30,7 +30,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/client_channel_factory.h" #include "src/core/ext/filters/deadline/deadline_filter.h" #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" From 51fd073b7c049206742a08f71ac919ad9097d303 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 24 Apr 2019 16:17:32 -0700 Subject: [PATCH 064/112] Don't add API to Optional --- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc | 4 ++-- .../ext/filters/client_channel/resolver_result_parsing.cc | 4 ++-- src/core/lib/gprpp/optional.h | 5 +---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 2070dfc696c..26d34e1b3f9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1530,8 +1530,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) { return; } ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); - locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, - args_, this); + locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, args_, + this); // Update the existing fallback policy. The fallback policy config and/or the // fallback addresses may be new. if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked(); diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index e868cd70bc6..a3bb6b9969b 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -401,8 +401,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling error:Duplicate entry")); } else { - Optional max_milli_tokens(false, 0); - Optional milli_token_ratio(false, 0); + Optional max_milli_tokens; + Optional milli_token_ratio; for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 5c519fe7ec0..fee081bc6b4 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,9 +26,6 @@ namespace grpc_core { template class Optional { public: - Optional() = default; - - Optional(bool set, T value) : set_(set), value_(value) {} void set(const T& val) { value_ = val; set_ = true; @@ -42,7 +39,7 @@ class Optional { private: bool set_ = false; - T value_; + T value_ = {}; }; } /* namespace grpc_core */ From 3433749d1b3f6e25fa5a0e9ad6387004cab07e2f Mon Sep 17 00:00:00 2001 From: Hope Casey-Allen Date: Wed, 24 Apr 2019 16:37:19 -0700 Subject: [PATCH 065/112] Add clarification to callback API documentation --- include/grpcpp/impl/codegen/client_callback.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h index e973e23f891..c897f6676d9 100644 --- a/include/grpcpp/impl/codegen/client_callback.h +++ b/include/grpcpp/impl/codegen/client_callback.h @@ -174,6 +174,8 @@ class ClientCallbackUnary { // StartWrite, or AddHold operations on the streaming object. Note that none of // the classes are pure; all reactions have a default empty reaction so that the // user class only needs to override those classes that it cares about. +// The reactor must be passed to the stub invocation before any of the below +// operations can be called. /// \a ClientBidiReactor is the interface for a bidirectional streaming RPC. template From f7c8e8be6260047301dd5c73f5fcbd849d5726b0 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 24 Apr 2019 16:51:59 -0700 Subject: [PATCH 066/112] clang tidy --- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc | 4 ++-- test/core/client_channel/service_config_test.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 26d34e1b3f9..9e9cee3d3a4 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1750,7 +1750,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - RefCountedPtr child_policy_config, + const RefCountedPtr& child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1845,7 +1845,7 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - RefCountedPtr child_policy_config, + const RefCountedPtr& child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // Construct update args. diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index fd5304c17d4..7a41283012e 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -137,7 +137,7 @@ class ErrorParser : public ServiceConfig::Parser { static const char* GlobalError() { return "ErrorParser : globalError"; } }; -void VerifyRegexMatch(grpc_error* error, std::regex e) { +void VerifyRegexMatch(grpc_error* error, const std::regex& e) { std::smatch match; std::string s(grpc_error_string(error)); EXPECT_TRUE(std::regex_search(s, match, e)); From 71ecf17eb73347063c7cc37fc5a519813ab52e71 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Wed, 24 Apr 2019 17:31:29 -0700 Subject: [PATCH 067/112] clang tidy --- src/core/ext/filters/client_channel/lb_policy/xds/xds.cc | 4 ++-- src/core/lib/gprpp/optional.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 9e9cee3d3a4..b25f66d1dfc 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -364,7 +364,7 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked( xds_grpclb_serverlist* serverlist, - RefCountedPtr child_policy_config, + const RefCountedPtr& child_policy_config, const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); @@ -412,7 +412,7 @@ class XdsLb : public LoadBalancingPolicy { void UpdateLocked( const LocalityList& locality_list, - RefCountedPtr child_policy_config, + const RefCountedPtr& child_policy_config, const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index fee081bc6b4..5bead0c88ee 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,6 +26,7 @@ namespace grpc_core { template class Optional { public: + Optional() { value_ = {}; } void set(const T& val) { value_ = val; set_ = true; @@ -39,7 +40,7 @@ class Optional { private: bool set_ = false; - T value_ = {}; + T value_; }; } /* namespace grpc_core */ From 05f37c8143c1276cfd9889d5c964229d506378cf Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Wed, 10 Apr 2019 15:25:00 -0700 Subject: [PATCH 068/112] Remove dependency on pubref/rules_proto. This commit resolves #18331. This commit resolves #18256. This commit resolves... another TODO that apparently didn't have an associated github issue. We swap out pubref's implementation of py_proto_library with our own, which more closely mirrors the interface of the internal py_proto_library, taking the descriptor file output of a proto_library rule as input. One minor change in behavior was introduced for simplicity. When a py_proto_library depends on a proto_library with a source proto file in a subdirectory of the bazel package, the import module of the resultant python library will reflect the package, *not* the full directory of the proto file, including both the bazel package and the subdirectories, as pubref did previously. This behavior also more closely mirrors google internal behavior. This commit also introduces a slightly more stringent bazel format script. Buildifier on its own will not take care of long lines, but by running yapf first, we end up with a more legible file. At the moment, there is no sanity check associated with this formatter. --- .gitignore | 1 + WORKSPACE | 7 - bazel/generate_cc.bzl | 200 ++++++++++------- bazel/grpc_python_deps.bzl | 14 +- bazel/protobuf.bzl | 84 ++++++++ bazel/python_rules.bzl | 203 ++++++++++++++++++ examples/BUILD | 12 +- examples/python/errors/client.py | 4 +- examples/python/errors/server.py | 4 +- .../test/_error_handling_example_test.py | 2 +- examples/python/multiprocessing/BUILD | 17 +- src/proto/grpc/channelz/BUILD | 5 + src/proto/grpc/health/v1/BUILD | 5 + src/proto/grpc/reflection/v1alpha/BUILD | 5 + src/proto/grpc/testing/BUILD | 41 ++-- src/proto/grpc/testing/proto2/BUILD.bazel | 30 +-- .../grpc_channelz/v1/BUILD.bazel | 26 +-- .../grpc_health/v1/BUILD.bazel | 19 +- .../grpc_reflection/v1alpha/BUILD.bazel | 17 +- .../grpcio_tests/tests/reflection/BUILD.bazel | 1 + tools/distrib/bazel_style.cfg | 4 + tools/distrib/format_bazel.sh | 39 ++++ .../linux/grpc_bazel_build_in_docker.sh | 3 +- 23 files changed, 545 insertions(+), 198 deletions(-) create mode 100644 bazel/protobuf.bzl create mode 100644 bazel/python_rules.bzl create mode 100644 tools/distrib/bazel_style.cfg create mode 100755 tools/distrib/format_bazel.sh diff --git a/.gitignore b/.gitignore index cde82bc3d36..db96e8ea92d 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ bazel-genfiles bazel-grpc bazel-out bazel-testlogs +bazel_format_virtual_environment/ # Debug output gdb.txt diff --git a/WORKSPACE b/WORKSPACE index 18f389edd24..51272707b1b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -17,13 +17,6 @@ register_toolchains( "//third_party/toolchains:cc-toolchain-clang-x86_64-default", ) -# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. -git_repository( - name = "org_pubref_rules_protobuf", - remote = "https://github.com/ghostwriternr/rules_protobuf", - tag = "v0.8.2.1-alpha", -) - git_repository( name = "io_bazel_rules_python", commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 8f30c84f6b9..83a0927da89 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -4,81 +4,130 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ -def generate_cc_impl(ctx): - """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] - includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports] - outs = [] - # label_len is length of the path from WORKSPACE root to the location of this build file - label_len = 0 - # proto_root is the directory relative to which generated include paths should be - proto_root = "" - if ctx.label.package: - # The +1 is for the trailing slash. - label_len += len(ctx.label.package) + 1 - if ctx.label.workspace_root: - label_len += len(ctx.label.workspace_root) + 1 - proto_root = "/" + ctx.label.workspace_root +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GRPC_PROTO_HEADER_FMT = "{}.grpc.pb.h" +_GRPC_PROTO_SRC_FMT = "{}.grpc.pb.cc" +_GRPC_PROTO_MOCK_HEADER_FMT = "{}_mock.grpc.pb.h" +_PROTO_HEADER_FMT = "{}.pb.h" +_PROTO_SRC_FMT = "{}.pb.cc" - if ctx.executable.plugin: - outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos] - outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos] - if ctx.attr.generate_mocks: - outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] - else: - outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos] - outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos] - out_files = [ctx.actions.declare_file(out) for out in outs] - dir_out = str(ctx.genfiles_dir.path + proto_root) +def _strip_package_from_path(label_package, path): + if not path.startswith(label_package + "/"): + fail("'{}' does not lie within '{}'.".format(path, label_package)) + return path[len(label_package + "/"):] - arguments = [] - if ctx.executable.plugin: - arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] - flags = list(ctx.attr.flags) - if ctx.attr.generate_mocks: - flags.append("generate_mock_code=true") - arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] - tools = [ctx.executable.plugin] - else: - arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - tools = [] +def _join_directories(directories): + massaged_directories = [directory for directory in directories if len(directory) != 0] + return "/".join(massaged_directories) - # Import protos relative to their workspace root so that protoc prints the - # right include paths. - for include in includes: - directory = include.path - if directory.startswith("external"): - external_sep = directory.find("/") - repository_sep = directory.find("/", external_sep + 1) - arguments += ["--proto_path=" + directory[:repository_sep]] +def generate_cc_impl(ctx): + """Implementation of the generate_cc rule.""" + protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] + includes = [ + f + for src in ctx.attr.srcs + for f in src.proto.transitive_imports + ] + outs = [] + proto_root = get_proto_root( + ctx.label.workspace_root, + ) + + label_package = _join_directories([ctx.label.workspace_root, ctx.label.package]) + if ctx.executable.plugin: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_SRC_FMT, + ) + for proto in protos + ] + if ctx.attr.generate_mocks: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_MOCK_HEADER_FMT, + ) + for proto in protos + ] else: - arguments += ["--proto_path=."] - # Include the output directory so that protoc puts the generated code in the - # right directory. - arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] - arguments += [proto.path for proto in protos] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _PROTO_SRC_FMT, + ) + for proto in protos + ] + out_files = [ctx.actions.declare_file(out) for out in outs] + dir_out = str(ctx.genfiles_dir.path + proto_root) - # create a list of well known proto files if the argument is non-None - well_known_proto_files = [] - if ctx.attr.well_known_protos: - f = ctx.attr.well_known_protos.files.to_list()[0].dirname - if f != "external/com_google_protobuf/src/google/protobuf": - print("Error: Only @com_google_protobuf//:well_known_protos is supported") + arguments = [] + if ctx.executable.plugin: + arguments += get_plugin_args( + ctx.executable.plugin, + ctx.attr.flags, + dir_out, + ctx.attr.generate_mocks, + ) + tools = [ctx.executable.plugin] else: - # f points to "external/com_google_protobuf/src/google/protobuf" - # add -I argument to protoc so it knows where to look for the proto files. - arguments += ["-I{0}".format(f + "/../..")] - well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] + arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] + tools = [] + + arguments += get_include_protoc_args(includes) - ctx.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = ctx.executable._protoc, - arguments = arguments, - ) + # Include the output directory so that protoc puts the generated code in the + # right directory. + arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] + arguments += [proto.path for proto in protos] - return struct(files=depset(out_files)) + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/com_google_protobuf/src/google/protobuf": + print( + "Error: Only @com_google_protobuf//:well_known_protos is supported", + ) + else: + # f points to "external/com_google_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [ + f + for f in ctx.attr.well_known_protos.files + ] + + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, + ) + + return struct(files = depset(out_files)) _generate_cc = rule( attrs = { @@ -96,10 +145,8 @@ _generate_cc = rule( mandatory = False, allow_empty = True, ), - "well_known_protos" : attr.label( - mandatory = False, - ), - "generate_mocks" : attr.bool( + "well_known_protos": attr.label(mandatory = False), + "generate_mocks": attr.bool( default = False, mandatory = False, ), @@ -115,7 +162,10 @@ _generate_cc = rule( ) def generate_cc(well_known_protos, **kwargs): - if well_known_protos: - _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) - else: - _generate_cc(**kwargs) + if well_known_protos: + _generate_cc( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + _generate_cc(**kwargs) diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl index ec3df19e03a..91438f3927b 100644 --- a/bazel/grpc_python_deps.bzl +++ b/bazel/grpc_python_deps.bzl @@ -1,16 +1,8 @@ load("//third_party/py:python_configure.bzl", "python_configure") load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") load("@grpc_python_dependencies//:requirements.bzl", "pip_install") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") def grpc_python_deps(): - # TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional. - if hasattr(native, "http_archive"): - python_configure(name = "local_config_python") - pip_repositories() - pip_install() - py_proto_repositories() - else: - print("Building Python gRPC with bazel 23.0+ is disabled pending " + - "resolution of https://github.com/grpc/grpc/issues/18256.") - + python_configure(name = "local_config_python") + pip_repositories() + pip_install() diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl new file mode 100644 index 00000000000..bddd0d70c7f --- /dev/null +++ b/bazel/protobuf.bzl @@ -0,0 +1,84 @@ +"""Utility functions for generating protobuf code.""" + +_PROTO_EXTENSION = ".proto" + +def get_proto_root(workspace_root): + """Gets the root protobuf directory. + + Args: + workspace_root: context.label.workspace_root + + Returns: + The directory relative to which generated include paths should be. + """ + if workspace_root: + return "/{}".format(workspace_root) + else: + return "" + +def _strip_proto_extension(proto_filename): + if not proto_filename.endswith(_PROTO_EXTENSION): + fail('"{}" does not end with "{}"'.format( + proto_filename, + _PROTO_EXTENSION, + )) + return proto_filename[:-len(_PROTO_EXTENSION)] + +def proto_path_to_generated_filename(proto_path, fmt_str): + """Calculates the name of a generated file for a protobuf path. + + For example, "examples/protos/helloworld.proto" might map to + "helloworld.pb.h". + + Args: + proto_path: The path to the .proto file. + fmt_str: A format string used to calculate the generated filename. For + example, "{}.pb.h" might be used to calculate a C++ header filename. + + Returns: + The generated filename. + """ + return fmt_str.format(_strip_proto_extension(proto_path)) + +def _get_include_directory(include): + directory = include.path + if directory.startswith("external"): + external_separator = directory.find("/") + repository_separator = directory.find("/", external_separator + 1) + return directory[:repository_separator] + else: + return "." + +def get_include_protoc_args(includes): + """Returns protoc args that imports protos relative to their import root. + + Args: + includes: A list of included proto files. + + Returns: + A list of arguments to be passed to protoc. For example, ["--proto_path=."]. + """ + return [ + "--proto_path={}".format(_get_include_directory(include)) + for include in includes + ] + +def get_plugin_args(plugin, flags, dir_out, generate_mocks): + """Returns arguments configuring protoc to use a plugin for a language. + + Args: + plugin: An executable file to run as the protoc plugin. + flags: The plugin flags to be passed to protoc. + dir_out: The output directory for the plugin. + generate_mocks: A bool indicating whether to generate mocks. + + Returns: + A list of protoc arguments configuring the plugin. + """ + augmented_flags = list(flags) + if generate_mocks: + augmented_flags.append("generate_mock_code=true") + return [ + "--plugin=protoc-gen-PLUGIN=" + plugin.path, + "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out, + ] diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl new file mode 100644 index 00000000000..bf6b4bec8d2 --- /dev/null +++ b/bazel/python_rules.bzl @@ -0,0 +1,203 @@ +"""Generates and compiles Python gRPC stubs from proto_library rules.""" + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GENERATED_PROTO_FORMAT = "{}_pb2.py" +_GENERATED_GRPC_PROTO_FORMAT = "{}_pb2_grpc.py" + +def _get_staged_proto_file(context, source_file): + if source_file.dirname == context.label.package: + return source_file + else: + copied_proto = context.actions.declare_file(source_file.basename) + context.actions.run_shell( + inputs = [source_file], + outputs = [copied_proto], + command = "cp {} {}".format(source_file.path, copied_proto.path), + mnemonic = "CopySourceProto", + ) + return copied_proto + +def _generate_py_impl(context): + protos = [] + for src in context.attr.deps: + for file in src.proto.direct_sources: + protos.append(_get_staged_proto_file(context, file)) + includes = [ + file + for src in context.attr.deps + for file in src.proto.transitive_imports + ] + proto_root = get_proto_root(context.label.workspace_root) + format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) + out_files = [ + context.actions.declare_file( + proto_path_to_generated_filename( + proto.basename, + format_str, + ), + ) + for proto in protos + ] + + arguments = [] + tools = [context.executable._protoc] + if context.executable.plugin: + arguments += get_plugin_args( + context.executable.plugin, + context.attr.flags, + context.genfiles_dir.path, + False, + ) + tools += [context.executable.plugin] + else: + arguments += [ + "--python_out={}:{}".format( + ",".join(context.attr.flags), + context.genfiles_dir.path, + ), + ] + + arguments += get_include_protoc_args(includes) + arguments += [ + "--proto_path={}".format(context.genfiles_dir.path) + for proto in protos + ] + for proto in protos: + massaged_path = proto.path + if massaged_path.startswith(context.genfiles_dir.path): + massaged_path = proto.path[len(context.genfiles_dir.path) + 1:] + arguments.append(massaged_path) + + well_known_proto_files = [] + if context.attr.well_known_protos: + well_known_proto_directory = context.attr.well_known_protos.files.to_list( + )[0].dirname + + arguments += ["-I{}".format(well_known_proto_directory + "/../..")] + well_known_proto_files = context.attr.well_known_protos.files.to_list() + + context.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = context.executable._protoc, + arguments = arguments, + mnemonic = "ProtocInvocation", + ) + return struct(files = depset(out_files)) + +__generate_py = rule( + attrs = { + "deps": attr.label_list( + mandatory = True, + allow_empty = False, + providers = ["proto"], + ), + "plugin": attr.label( + executable = True, + providers = ["files_to_run"], + cfg = "host", + ), + "flags": attr.string_list( + mandatory = False, + allow_empty = True, + ), + "well_known_protos": attr.label(mandatory = False), + "_protoc": attr.label( + default = Label("//external:protocol_compiler"), + executable = True, + cfg = "host", + ), + }, + output_to_genfiles = True, + implementation = _generate_py_impl, +) + +def _generate_py(well_known_protos, **kwargs): + if well_known_protos: + __generate_py( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + __generate_py(**kwargs) + +_WELL_KNOWN_PROTO_LIBS = [ + "@com_google_protobuf//:any_proto", + "@com_google_protobuf//:api_proto", + "@com_google_protobuf//:compiler_plugin_proto", + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:field_mask_proto", + "@com_google_protobuf//:source_context_proto", + "@com_google_protobuf//:struct_proto", + "@com_google_protobuf//:timestamp_proto", + "@com_google_protobuf//:type_proto", + "@com_google_protobuf//:wrappers_proto", +] + +def py_proto_library( + name, + deps, + well_known_protos = True, + proto_only = False, + **kwargs): + """Generate python code for a protobuf. + + Args: + name: The name of the target. + deps: A list of dependencies. Must contain a single element. + well_known_protos: A bool indicating whether or not to include well-known + protos. + proto_only: A bool indicating whether to generate vanilla protobuf code + or to also generate gRPC code. + """ + if len(deps) > 1: + fail("The supported length of 'deps' is 1.") + + codegen_target = "_{}_codegen".format(name) + codegen_grpc_target = "_{}_grpc_codegen".format(name) + + well_known_proto_rules = _WELL_KNOWN_PROTO_LIBS if well_known_protos else [] + + _generate_py( + name = codegen_target, + deps = deps, + well_known_protos = well_known_protos, + **kwargs + ) + + if not proto_only: + _generate_py( + name = codegen_grpc_target, + deps = deps, + plugin = "//:grpc_python_plugin", + well_known_protos = well_known_protos, + **kwargs + ) + + native.py_library( + name = name, + srcs = [ + ":{}".format(codegen_grpc_target), + ":{}".format(codegen_target), + ], + deps = [requirement("protobuf")], + **kwargs + ) + else: + native.py_library( + name = name, + srcs = [":{}".format(codegen_target), ":{}".format(codegen_target)], + deps = [requirement("protobuf")], + **kwargs + ) diff --git a/examples/BUILD b/examples/BUILD index d2b39b87f4d..d5fb6903d7c 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -16,9 +16,8 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) -load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -45,11 +44,14 @@ grpc_proto_library( srcs = ["protos/keyvaluestore.proto"], ) +proto_library( + name = "helloworld_proto_descriptor", + srcs = ["protos/helloworld.proto"], +) + py_proto_library( name = "py_helloworld", - protos = ["protos/helloworld.proto"], - with_grpc = True, - deps = [requirement('protobuf'),], + deps = [":helloworld_proto_descriptor"], ) cc_binary( diff --git a/examples/python/errors/client.py b/examples/python/errors/client.py index a79b8fce1bd..c762d798dc2 100644 --- a/examples/python/errors/client.py +++ b/examples/python/errors/client.py @@ -20,8 +20,8 @@ import grpc from grpc_status import rpc_status from google.rpc import error_details_pb2 -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/errors/server.py b/examples/python/errors/server.py index f49586b848a..50d4a2ac671 100644 --- a/examples/python/errors/server.py +++ b/examples/python/errors/server.py @@ -24,8 +24,8 @@ from grpc_status import rpc_status from google.protobuf import any_pb2 from google.rpc import code_pb2, status_pb2, error_details_pb2 -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py index a79ca45e2a1..9eb81ba3742 100644 --- a/examples/python/errors/test/_error_handling_example_test.py +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -26,7 +26,7 @@ import logging import grpc -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2_grpc from examples.python.errors import client as error_handling_client from examples.python.errors import server as error_handling_server diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 6de1e947d85..0e135f471f2 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -15,12 +15,17 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") -py_proto_library( +proto_library( name = "prime_proto", - protos = ["prime.proto",], - deps = [requirement("protobuf")], + srcs = ["prime.proto"] +) + +py_proto_library( + name = "prime_proto_pb2", + deps = [":prime_proto"], + well_known_protos = False, ) py_binary( @@ -29,7 +34,7 @@ py_binary( srcs = ["client.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto", + ":prime_proto_pb2", ], default_python_version = "PY3", ) @@ -40,7 +45,7 @@ py_binary( srcs = ["server.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto" + ":prime_proto_pb2" ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index b6b485e3e8d..1d80ec23af1 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -25,6 +25,11 @@ grpc_proto_library( well_known_protos = True, ) +proto_library( + name = "channelz_proto_descriptors", + srcs = ["channelz.proto"], +) + filegroup( name = "channelz_proto_file", srcs = [ diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index 38a7d992e06..fc58e8a1770 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["health.proto"], ) +proto_library( + name = "health_proto_descriptor", + srcs = ["health.proto"], +) + filegroup( name = "health_proto_file", srcs = [ diff --git a/src/proto/grpc/reflection/v1alpha/BUILD b/src/proto/grpc/reflection/v1alpha/BUILD index 4d919d029ee..5424c0d867e 100644 --- a/src/proto/grpc/reflection/v1alpha/BUILD +++ b/src/proto/grpc/reflection/v1alpha/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["reflection.proto"], ) +proto_library( + name = "reflection_proto_descriptor", + srcs = ["reflection.proto"], +) + filegroup( name = "reflection_proto_file", srcs = [ diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 9876d5160a1..16e47d81061 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -16,7 +16,7 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_package(name = "testing", visibility = "public") @@ -61,13 +61,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "empty_proto_descriptor", + srcs = ["empty.proto"], +) + py_proto_library( name = "py_empty_proto", - protos = ["empty.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":empty_proto_descriptor"], ) grpc_proto_library( @@ -76,13 +77,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "messages_proto_descriptor", + srcs = ["messages.proto"], +) + py_proto_library( name = "py_messages_proto", - protos = ["messages.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":messages_proto_descriptor"], ) grpc_proto_library( @@ -144,16 +146,19 @@ grpc_proto_library( ], ) +proto_library( + name = "test_proto_descriptor", + srcs = ["test.proto"], + deps = [ + ":empty_proto_descriptor", + ":messages_proto_descriptor", + ], +) + py_proto_library( name = "py_test_proto", - protos = ["test.proto",], - with_grpc = True, deps = [ - requirement('protobuf'), - ], - proto_deps = [ - ":py_empty_proto", - ":py_messages_proto", + ":test_proto_descriptor", ] ) diff --git a/src/proto/grpc/testing/proto2/BUILD.bazel b/src/proto/grpc/testing/proto2/BUILD.bazel index c4c4f004efb..e939c523a64 100644 --- a/src/proto/grpc/testing/proto2/BUILD.bazel +++ b/src/proto/grpc/testing/proto2/BUILD.bazel @@ -1,30 +1,32 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) +load("//bazel:python_rules.bzl", "py_proto_library") + +proto_library( + name = "empty2_proto_descriptor", + srcs = ["empty2.proto"], +) py_proto_library( name = "empty2_proto", - protos = [ - "empty2.proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_proto_descriptor", ], ) +proto_library( + name = "empty2_extensions_proto_descriptor", + srcs = ["empty2_extensions.proto"], + deps = [ + ":empty2_proto_descriptor", + ] +) + py_proto_library( name = "empty2_extensions_proto", - protos = [ - "empty2_extensions.proto", - ], - proto_deps = [ - ":empty2_proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_extensions_proto_descriptor", ], ) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel index aae8cedb760..eccc166577d 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -1,30 +1,10 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_channelz_proto", - srcs = [ - "//src/proto/grpc/channelz:channelz_proto_file", - ], - outs = ["channelz.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_channelz_proto", - protos = ["mv_channelz_proto",], - imports = [ - "external/com_google_protobuf/src/", - ], - inputs = [ - "@com_google_protobuf//:well_known_protos", - ], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + well_known_protos = True, + deps = ["//src/proto/grpc/channelz:channelz_proto_descriptors"], ) py_library( diff --git a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel index ce3121fa90e..9e4fff34581 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel +++ b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel @@ -1,24 +1,9 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_health_proto", - srcs = [ - "//src/proto/grpc/health/v1:health_proto_file", - ], - outs = ["health.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_health_proto", - protos = [":mv_health_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/health/v1:health_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel index 3a2ba263715..6aaa4dd3bdd 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel @@ -1,24 +1,11 @@ +load("//bazel:python_rules.bzl", "py_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_reflection_proto", - srcs = [ - "//src/proto/grpc/reflection/v1alpha:reflection_proto_file", - ], - outs = ["reflection.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_reflection_proto", - protos = [":mv_reflection_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/reflection/v1alpha:reflection_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_tests/tests/reflection/BUILD.bazel b/src/python/grpcio_tests/tests/reflection/BUILD.bazel index c0efb0b7cef..b635b721631 100644 --- a/src/python/grpcio_tests/tests/reflection/BUILD.bazel +++ b/src/python/grpcio_tests/tests/reflection/BUILD.bazel @@ -14,6 +14,7 @@ py_test( "//src/python/grpcio_tests/tests/unit:test_common", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing/proto2:empty2_extensions_proto", + "//src/proto/grpc/testing/proto2:empty2_proto", requirement('protobuf'), ], imports=["../../",], diff --git a/tools/distrib/bazel_style.cfg b/tools/distrib/bazel_style.cfg new file mode 100644 index 00000000000..a5a1fea4aba --- /dev/null +++ b/tools/distrib/bazel_style.cfg @@ -0,0 +1,4 @@ +[style] +based_on_style = google +allow_split_before_dict_value = False +spaces_around_default_or_named_assign = True diff --git a/tools/distrib/format_bazel.sh b/tools/distrib/format_bazel.sh new file mode 100755 index 00000000000..ee230118efb --- /dev/null +++ b/tools/distrib/format_bazel.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2019 The gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set=-ex + +VIRTUAL_ENV=bazel_format_virtual_environment + +CONFIG_PATH="$(dirname ${0})/bazel_style.cfg" + +python -m virtualenv ${VIRTUAL_ENV} +PYTHON=${VIRTUAL_ENV}/bin/python +"$PYTHON" -m pip install --upgrade pip==10.0.1 +"$PYTHON" -m pip install --upgrade futures +"$PYTHON" -m pip install yapf==0.20.0 + +pushd "$(dirname "${0}")/../.." +FILES=$(find . -path ./third_party -prune -o -name '*.bzl' -print) +echo "${FILES}" | xargs "$PYTHON" -m yapf -i --style="${CONFIG_PATH}" + +if ! which buildifier &>/dev/null; then + echo 'buildifer must be installed.' >/dev/stderr + exit 1 +fi + +echo "${FILES}" | xargs buildifier --type=bzl + +popd diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 3dd0167b7c0..24598f43f02 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,5 +24,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc -#TODO(yfen): add back examples/... to build targets once python rules issues are resolved -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... From 9cac231163d37d6b57ed9e01c878df9f0529d7eb Mon Sep 17 00:00:00 2001 From: yang-g Date: Thu, 25 Apr 2019 09:06:28 -0700 Subject: [PATCH 069/112] Inline start the tcp servers --- src/core/lib/surface/server.cc | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc index c6983ea9c95..89188be8176 100644 --- a/src/core/lib/surface/server.cc +++ b/src/core/lib/surface/server.cc @@ -1098,20 +1098,6 @@ void* grpc_server_register_method( return m; } -static void start_listeners(void* s, grpc_error* error) { - grpc_server* server = static_cast(s); - for (listener* l = server->listeners; l; l = l->next) { - l->start(server, l->arg, server->pollsets, server->pollset_count); - } - - gpr_mu_lock(&server->mu_global); - server->starting = false; - gpr_cv_signal(&server->starting_cv); - gpr_mu_unlock(&server->mu_global); - - server_unref(server); -} - void grpc_server_start(grpc_server* server) { size_t i; grpc_core::ExecCtx exec_ctx; @@ -1133,13 +1119,18 @@ void grpc_server_start(grpc_server* server) { request_matcher_init(&rm->matcher, server); } - server_ref(server); + gpr_mu_lock(&server->mu_global); server->starting = true; - GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE( - start_listeners, server, - grpc_core::Executor::Scheduler(grpc_core::ExecutorJobType::SHORT)), - GRPC_ERROR_NONE); + gpr_mu_unlock(&server->mu_global); + + for (listener* l = server->listeners; l; l = l->next) { + l->start(server, l->arg, server->pollsets, server->pollset_count); + } + + gpr_mu_lock(&server->mu_global); + server->starting = false; + gpr_cv_signal(&server->starting_cv); + gpr_mu_unlock(&server->mu_global); } void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets, From 4de4a7da7b45b988c13cd6529ed034b7fff74ef2 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 10:27:01 -0700 Subject: [PATCH 070/112] Reenable python bazel tests --- .../python/wait_for_ready/wait_for_ready_example.py | 4 ++-- .../linux/grpc_python_bazel_test_in_docker.sh | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 7c16b9bd4a1..effafd88ee5 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -22,8 +22,8 @@ import threading import grpc -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.INFO) diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 3ca4673ca08..d844cff7f9a 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -23,10 +23,9 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc (cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') -#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 -#cd /var/local/git/grpc/test -#bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -#bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... -#bazel clean --expunge -#bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -#bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +cd /var/local/git/grpc/test +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +bazel clean --expunge +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... From e457584c05fbbdecc6f4fe9356cea2450c4fd5d3 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 25 Apr 2019 11:07:36 -0700 Subject: [PATCH 071/112] Address comments --- .../dns/c_ares/grpc_ares_ev_driver_libuv.cc | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index e69b824304d..c29fa44a353 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -47,9 +47,13 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { handle_ = New(); uv_poll_init_socket(uv_default_loop(), handle_, as); handle_->data = this; + GRPC_COMBINER_REF(combiner_, "libuv ares event driver"); } - ~GrpcPolledFdLibuv() { gpr_free(name_); } + ~GrpcPolledFdLibuv() { + gpr_free(name_); + GRPC_COMBINER_UNREF(combiner_, "libuv ares event driver"); + } void RegisterForOnReadableLocked(grpc_closure* read_closure) override { GPR_ASSERT(read_closure_ == nullptr); @@ -73,18 +77,26 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { return false; } - void ShutdownLocked(grpc_error* error) override { - grpc_core::ExecCtx exec_ctx; + void ShutdownInternal(grpc_error* error) { uv_poll_stop(handle_); uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); - if (read_closure_) { + if (read_closure_ != nullptr) { GRPC_CLOSURE_SCHED(read_closure_, GRPC_ERROR_CANCELLED); } - if (write_closure_) { + if (write_closure_ != nullptr) { GRPC_CLOSURE_SCHED(write_closure_, GRPC_ERROR_CANCELLED); } } + void ShutdownLocked(grpc_error* error) override { + if (grpc_core::ExecCtx::Get() == nullptr) { + grpc_core::ExecCtx exec_ctx; + ShutdownInternal(error); + } else { + ShutdownInternal(error); + } + } + ares_socket_t GetWrappedAresSocketLocked() override { return as_; } const char* GetName() override { return name_; } @@ -107,8 +119,9 @@ struct AresUvPollCbArg { int events; }; -static void inner_callback(void* arg, grpc_error* error) { - AresUvPollCbArg* arg_struct = reinterpret_cast(arg); +static void ares_uv_poll_cb_locked(void* arg, grpc_error* error) { + grpc_core::UniquePtr arg_struct( + reinterpret_cast(arg)); uv_poll_t* handle = arg_struct->handle; int status = arg_struct->status; int events = arg_struct->events; @@ -120,18 +133,19 @@ static void inner_callback(void* arg, grpc_error* error) { grpc_error_set_str(error, GRPC_ERROR_STR_OS_ERROR, grpc_slice_from_static_string(uv_strerror(status))); } - if ((events & UV_READABLE) && polled_fd->read_closure_) { + if (events & UV_READABLE) { + GPR_ASSERT(polled_fd->read_closure_ != nullptr); GRPC_CLOSURE_SCHED(polled_fd->read_closure_, error); polled_fd->read_closure_ = nullptr; polled_fd->poll_events_ &= ~UV_READABLE; } - if ((events & UV_WRITABLE) && polled_fd->write_closure_) { + if (events & UV_WRITABLE) { + GPR_ASSERT(polled_fd->write_closure_ != nullptr); GRPC_CLOSURE_SCHED(polled_fd->write_closure_, error); polled_fd->write_closure_ = nullptr; polled_fd->poll_events_ &= ~UV_WRITABLE; } uv_poll_start(handle, polled_fd->poll_events_, ares_uv_poll_cb); - Delete(arg_struct); } void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { @@ -140,7 +154,7 @@ void ares_uv_poll_cb(uv_poll_t* handle, int status, int events) { reinterpret_cast(handle->data); AresUvPollCbArg* arg = New(handle, status, events); GRPC_CLOSURE_SCHED( - GRPC_CLOSURE_CREATE(inner_callback, arg, + GRPC_CLOSURE_CREATE(ares_uv_poll_cb_locked, arg, grpc_combiner_scheduler(polled_fd->combiner_)), GRPC_ERROR_NONE); } From 3377e49bc7784514f0bc9d593531c30d39fe5250 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Thu, 25 Apr 2019 11:40:56 -0700 Subject: [PATCH 072/112] Fix build errors --- BUILD.gn | 1 + CMakeLists.txt | 3 +++ Makefile | 3 +++ build.yaml | 1 + gRPC-C++.podspec | 1 + tools/doxygen/Doxyfile.c++ | 1 + tools/doxygen/Doxyfile.c++.internal | 1 + tools/run_tests/generated/sources_and_headers.json | 2 ++ 8 files changed, 13 insertions(+) diff --git a/BUILD.gn b/BUILD.gn index 2518db149d7..b55e1389a43 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1087,6 +1087,7 @@ config("grpc_config") { "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 3479d17ad06..4e13c541d9a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3039,6 +3039,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h @@ -3646,6 +3647,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h @@ -4630,6 +4632,7 @@ foreach(_hdr include/grpcpp/security/auth_metadata_processor.h include/grpcpp/security/auth_metadata_processor_impl.h include/grpcpp/security/credentials.h + include/grpcpp/security/credentials_impl.h include/grpcpp/security/server_credentials.h include/grpcpp/security/server_credentials_impl.h include/grpcpp/server.h diff --git a/Makefile b/Makefile index 5d10bd9f4b7..e87513c4067 100644 --- a/Makefile +++ b/Makefile @@ -5379,6 +5379,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ @@ -5994,6 +5995,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ @@ -6927,6 +6929,7 @@ PUBLIC_HEADERS_CXX += \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ + include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ diff --git a/build.yaml b/build.yaml index f7d2e8be0e9..9e9b388e047 100644 --- a/build.yaml +++ b/build.yaml @@ -1381,6 +1381,7 @@ filegroups: - include/grpcpp/security/auth_metadata_processor.h - include/grpcpp/security/auth_metadata_processor_impl.h - include/grpcpp/security/credentials.h + - include/grpcpp/security/credentials_impl.h - include/grpcpp/security/server_credentials.h - include/grpcpp/security/server_credentials_impl.h - include/grpcpp/server.h diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3141ecdbe17..ef12a33ad33 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -116,6 +116,7 @@ Pod::Spec.new do |s| 'include/grpcpp/security/auth_metadata_processor.h', 'include/grpcpp/security/auth_metadata_processor_impl.h', 'include/grpcpp/security/credentials.h', + 'include/grpcpp/security/credentials_impl.h', 'include/grpcpp/security/server_credentials.h', 'include/grpcpp/security/server_credentials_impl.h', 'include/grpcpp/server.h', diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 2a71e73a839..56b3fb0e3df 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -1008,6 +1008,7 @@ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ +include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 438cd023166..4bd0150c304 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1010,6 +1010,7 @@ include/grpcpp/security/auth_context.h \ include/grpcpp/security/auth_metadata_processor.h \ include/grpcpp/security/auth_metadata_processor_impl.h \ include/grpcpp/security/credentials.h \ +include/grpcpp/security/credentials_impl.h \ include/grpcpp/security/server_credentials.h \ include/grpcpp/security/server_credentials_impl.h \ include/grpcpp/server.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 4e5f268b38f..0a084411829 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -10186,6 +10186,7 @@ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", @@ -10308,6 +10309,7 @@ "include/grpcpp/security/auth_metadata_processor.h", "include/grpcpp/security/auth_metadata_processor_impl.h", "include/grpcpp/security/credentials.h", + "include/grpcpp/security/credentials_impl.h", "include/grpcpp/security/server_credentials.h", "include/grpcpp/security/server_credentials_impl.h", "include/grpcpp/server.h", From 1c65fd19e835264b0c040ac6a41ac76a3f66970a Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 12:55:58 -0700 Subject: [PATCH 073/112] Fix wait_for_ready example for ipv4-only environments like Kokoro --- examples/python/wait_for_ready/wait_for_ready_example.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index effafd88ee5..d2f6f2f7ba1 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -33,8 +33,12 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @contextmanager def get_free_loopback_tcp_port(): - tcp_socket = socket.socket(socket.AF_INET6) - tcp_socket.bind(('', 0)) + if socket.has_ipv6: + tcp_socket = socket.socket(socket.AF_INET6) + tcp_socket.bind(('', 0)) + else: + tcp_socket = socket.socket(socket.AF_INET) + tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() yield "[::1]:%s" % (address_tuple[1]) tcp_socket.close() From aec0860ebf861c24c13595b96563a1bebb34988f Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 12:56:46 -0700 Subject: [PATCH 074/112] Remove redundant line --- examples/python/wait_for_ready/wait_for_ready_example.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index d2f6f2f7ba1..3875c2e75b5 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -35,10 +35,9 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 def get_free_loopback_tcp_port(): if socket.has_ipv6: tcp_socket = socket.socket(socket.AF_INET6) - tcp_socket.bind(('', 0)) else: tcp_socket = socket.socket(socket.AF_INET) - tcp_socket.bind(('', 0)) + tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() yield "[::1]:%s" % (address_tuple[1]) tcp_socket.close() From 5391d8427e015cea24ea6d24888f893c51f1b121 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Thu, 25 Apr 2019 13:53:23 -0700 Subject: [PATCH 075/112] Moar ipv6 --- examples/python/wait_for_ready/wait_for_ready_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 3875c2e75b5..a0f076e894a 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -39,7 +39,7 @@ def get_free_loopback_tcp_port(): tcp_socket = socket.socket(socket.AF_INET) tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() - yield "[::1]:%s" % (address_tuple[1]) + yield "localhost:%s" % (address_tuple[1]) tcp_socket.close() From 156d743c3717130f0adcf2daf82f8cf45744e549 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 25 Apr 2019 16:38:10 -0700 Subject: [PATCH 076/112] Reviewer comments --- BUILD | 2 - BUILD.gn | 2 - CMakeLists.txt | 6 - Makefile | 6 - build.yaml | 2 - config.m4 | 1 - config.w32 | 1 - gRPC-C++.podspec | 1 - gRPC-Core.podspec | 3 - grpc.gemspec | 2 - grpc.gyp | 4 - package.xml | 2 - .../filters/client_channel/client_channel.cc | 26 +- .../client_channel/client_channel_plugin.cc | 8 +- .../health/health_check_parser.cc | 84 ----- .../health/health_check_parser.h | 3 +- .../client_channel/lb_policy/grpclb/grpclb.cc | 39 ++- .../client_channel/lb_policy/xds/xds.cc | 32 +- .../client_channel/lb_policy_registry.cc | 34 +- .../client_channel/lb_policy_registry.h | 9 +- .../client_channel/resolver_result_parsing.cc | 312 ++++++++++-------- .../client_channel/resolver_result_parsing.h | 33 +- .../client_channel/resolving_lb_policy.cc | 2 +- .../client_channel/resolving_lb_policy.h | 2 +- .../filters/client_channel/service_config.cc | 8 +- .../filters/client_channel/service_config.h | 52 ++- .../message_size/message_size_filter.cc | 22 +- src/core/lib/gprpp/optional.h | 2 +- src/core/lib/iomgr/error.h | 19 ++ src/python/grpcio/grpc_core_dependencies.py | 1 - .../client_channel/service_config_test.cc | 116 +++---- tools/doxygen/Doxyfile.core.internal | 2 - .../generated/sources_and_headers.json | 3 - 33 files changed, 371 insertions(+), 470 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.cc diff --git a/BUILD b/BUILD index c9ff663201e..1735961eb61 100644 --- a/BUILD +++ b/BUILD @@ -1082,7 +1082,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/global_subchannel_pool.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc", - "src/core/ext/filters/client_channel/health/health_check_parser.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", @@ -1109,7 +1108,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/connector.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", - "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", diff --git a/BUILD.gn b/BUILD.gn index 4452bfa2cae..10b0f1a7fdd 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -260,8 +260,6 @@ config("grpc_config") { "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", - "src/core/ext/filters/client_channel/health/health_check_parser.cc", - "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 15a8697c9a0..0edd7fd54ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1235,7 +1235,6 @@ add_library(grpc src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1591,7 +1590,6 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1972,7 +1970,6 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2298,7 +2295,6 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2635,7 +2631,6 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -3508,7 +3503,6 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_parser.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc diff --git a/Makefile b/Makefile index 7a80e4c0731..57530500b15 100644 --- a/Makefile +++ b/Makefile @@ -3695,7 +3695,6 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4045,7 +4044,6 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4419,7 +4417,6 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4732,7 +4729,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -5043,7 +5039,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -5892,7 +5887,6 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ diff --git a/build.yaml b/build.yaml index 53fd95f5c06..80519946295 100644 --- a/build.yaml +++ b/build.yaml @@ -576,7 +576,6 @@ filegroups: - src/core/ext/filters/client_channel/connector.h - src/core/ext/filters/client_channel/global_subchannel_pool.h - src/core/ext/filters/client_channel/health/health_check_client.h - - src/core/ext/filters/client_channel/health/health_check_parser.h - src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/lb_policy.h @@ -606,7 +605,6 @@ filegroups: - src/core/ext/filters/client_channel/connector.cc - src/core/ext/filters/client_channel/global_subchannel_pool.cc - src/core/ext/filters/client_channel/health/health_check_client.cc - - src/core/ext/filters/client_channel/health/health_check_parser.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc diff --git a/config.m4 b/config.m4 index e7d3a5daf4e..ab2a717cbcd 100644 --- a/config.m4 +++ b/config.m4 @@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \ - src/core/ext/filters/client_channel/health/health_check_parser.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ diff --git a/config.w32 b/config.w32 index 8a6529faae2..02eb773ebb8 100644 --- a/config.w32 +++ b/config.w32 @@ -323,7 +323,6 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\connector.cc " + "src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + - "src\\core\\ext\\filters\\client_channel\\health\\health_check_parser.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 7ca1477a16b..de1bb0ae57f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -367,7 +367,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', - 'src/core/ext/filters/client_channel/health/health_check_parser.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 13c2a2cf9d0..5cf45c63cef 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -347,7 +347,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', - 'src/core/ext/filters/client_channel/health/health_check_parser.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -797,7 +796,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', - 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -991,7 +989,6 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/health/health_check_client.h', - 'src/core/ext/filters/client_channel/health/health_check_parser.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', diff --git a/grpc.gemspec b/grpc.gemspec index bca4674c761..15c26f11569 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -281,7 +281,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/connector.h ) s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) - s.files += %w( src/core/ext/filters/client_channel/health/health_check_parser.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) @@ -734,7 +733,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/connector.cc ) s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) - s.files += %w( src/core/ext/filters/client_channel/health/health_check_parser.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) diff --git a/grpc.gyp b/grpc.gyp index d4db059dc0a..40dc88d7474 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -530,7 +530,6 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', - 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -795,7 +794,6 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', - 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1041,7 +1039,6 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', - 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1298,7 +1295,6 @@ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', - 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', diff --git a/package.xml b/package.xml index 3af95c9a727..c3f4e17dd12 100644 --- a/package.xml +++ b/package.xml @@ -286,7 +286,6 @@ - @@ -739,7 +738,6 @@ - diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f0972ef4c70..f0bc3417a2b 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -240,6 +240,7 @@ class ChannelData { const size_t per_rpc_retry_buffer_size_; grpc_channel_stack* owning_stack_; ClientChannelFactory* client_channel_factory_; + UniquePtr server_name_; // Initialized shortly after construction. channelz::ClientChannelNode* channelz_node_ = nullptr; @@ -263,7 +264,7 @@ class ChannelData { OrphanablePtr resolving_lb_policy_; grpc_connectivity_state_tracker state_tracker_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; - const char* health_check_service_name_ = nullptr; + UniquePtr health_check_service_name_; // // Fields accessed from both data plane and control plane combiners. @@ -762,12 +763,11 @@ class ChannelData::ConnectivityStateAndPickerSetter { class ChannelData::ServiceConfigSetter { public: ServiceConfigSetter( - ChannelData* chand, UniquePtr server_name, + ChannelData* chand, Optional retry_throttle_data, RefCountedPtr service_config) : chand_(chand), - server_name_(std::move(server_name)), retry_throttle_data_(retry_throttle_data), service_config_(std::move(service_config)) { GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter"); @@ -785,7 +785,7 @@ class ChannelData::ServiceConfigSetter { if (self->retry_throttle_data_.has_value()) { chand->retry_throttle_data_ = internal::ServerRetryThrottleMap::GetDataForServer( - self->server_name_.get(), + chand->server_name_.get(), self->retry_throttle_data_.value().max_milli_tokens, self->retry_throttle_data_.value().milli_token_ratio); } @@ -803,7 +803,6 @@ class ChannelData::ServiceConfigSetter { } ChannelData* chand_; - UniquePtr server_name_; Optional retry_throttle_data_; RefCountedPtr service_config_; @@ -948,7 +947,7 @@ class ChannelData::ClientChannelControlHelper if (chand_->health_check_service_name_ != nullptr) { args_to_add[0] = grpc_channel_arg_string_create( const_cast("grpc.temp.health_check"), - const_cast(chand_->health_check_service_name_)); + const_cast(chand_->health_check_service_name_.get())); num_args_to_add++; } args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( @@ -1067,6 +1066,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) "filter"); return; } + grpc_uri* uri = grpc_uri_parse(server_uri, true); + GPR_ASSERT(uri->path[0] != '\0'); + server_name_.reset( + gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); char* proxy_name = nullptr; grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, @@ -1135,11 +1138,12 @@ bool ChannelData::ProcessResolverResultLocked( gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", chand, service_config_json); } + chand->health_check_service_name_.reset( + gpr_strdup(resolver_result.health_check_service_name())); // Create service config setter to update channel state in the data // plane combiner. Destroys itself when done. - New( - chand, UniquePtr(gpr_strdup(resolver_result.server_name())), - resolver_result.retry_throttle_data(), resolver_result.service_config()); + New(chand, resolver_result.retry_throttle_data(), + resolver_result.service_config()); // Swap out the data used by GetChannelInfo(). bool service_config_changed; { @@ -1156,8 +1160,6 @@ bool ChannelData::ProcessResolverResultLocked( // Return results. *lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_config = resolver_result.lb_policy_config(); - chand->health_check_service_name_ = - resolver_result.health_check_service_name(); return service_config_changed; } @@ -3101,7 +3103,7 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) { // it. service_config_call_data_ = ServiceConfig::CallData(chand->service_config(), path_); - if (!service_config_call_data_.empty()) { + if (service_config_call_data_.service_config() != nullptr) { call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value = &service_config_call_data_; method_params_ = static_cast( diff --git a/src/core/ext/filters/client_channel/client_channel_plugin.cc b/src/core/ext/filters/client_channel/client_channel_plugin.cc index 877111b8a38..e564df8be33 100644 --- a/src/core/ext/filters/client_channel/client_channel_plugin.cc +++ b/src/core/ext/filters/client_channel/client_channel_plugin.cc @@ -27,7 +27,6 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/global_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/http_proxy.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" @@ -50,14 +49,9 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) { builder, static_cast(arg), nullptr, nullptr); } -void grpc_service_config_register_parsers() { - grpc_core::internal::ClientChannelServiceConfigParser::Register(); - grpc_core::HealthCheckParser::Register(); -} - void grpc_client_channel_init(void) { grpc_core::ServiceConfig::Init(); - grpc_service_config_register_parsers(); + grpc_core::internal::ClientChannelServiceConfigParser::Register(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::internal::ServerRetryThrottleMap::Init(); diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.cc b/src/core/ext/filters/client_channel/health/health_check_parser.cc deleted file mode 100644 index 7760e22b686..00000000000 --- a/src/core/ext/filters/client_channel/health/health_check_parser.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" - -namespace grpc_core { -namespace { -size_t g_health_check_parser_index; -} - -UniquePtr HealthCheckParser::ParseGlobalParams( - const grpc_json* json, grpc_error** error) { - GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); - const char* service_name = nullptr; - InlinedVector error_list; - for (grpc_json* field = json->child; field != nullptr; field = field->next) { - if (field->key == nullptr) { - GPR_DEBUG_ASSERT(false); - continue; - } - if (strcmp(field->key, "healthCheckConfig") == 0) { - if (field->type != GRPC_JSON_OBJECT) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:healthCheckConfig error:should be of type object"); - return nullptr; - } - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) { - GPR_DEBUG_ASSERT(false); - continue; - } - if (strcmp(sub_field->key, "serviceName") == 0) { - if (service_name != nullptr) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:serviceName error:Duplicate " - "entry")); - continue; - } - if (sub_field->type != GRPC_JSON_STRING) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:serviceName error:should be of type string")); - continue; - } - service_name = sub_field->value; - } - } - } - } - if (error_list.empty()) { - if (service_name == nullptr) return nullptr; - return UniquePtr( - New(service_name)); - } - *error = ServiceConfig::CreateErrorFromVector("field:healthCheckConfig", - &error_list); - return nullptr; -} - -void HealthCheckParser::Register() { - g_health_check_parser_index = ServiceConfig::RegisterParser( - UniquePtr(New())); -} - -size_t HealthCheckParser::ParserIndex() { return g_health_check_parser_index; } - -} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h index 036cafc68b7..0143f147152 100644 --- a/src/core/ext/filters/client_channel/health/health_check_parser.h +++ b/src/core/ext/filters/client_channel/health/health_check_parser.h @@ -24,7 +24,7 @@ #include "src/core/ext/filters/client_channel/service_config.h" namespace grpc_core { - +#if 0 class HealthCheckParsedObject : public ServiceConfig::ParsedConfig { public: HealthCheckParsedObject(const char* service_name) @@ -47,5 +47,6 @@ class HealthCheckParser : public ServiceConfig::Parser { static size_t ParserIndex(); }; +#endif } // namespace grpc_core #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index fe99e8bc7c0..4bf4dc0ac0b 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -120,7 +120,8 @@ constexpr char kGrpclb[] = "grpclb"; class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { public: - ParsedGrpcLbConfig(RefCountedPtr child_policy) + explicit ParsedGrpcLbConfig( + RefCountedPtr child_policy) : child_policy_(std::move(child_policy)) {} const char* name() const override { return kGrpclb; } @@ -1142,13 +1143,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { - // If the fallback-at-startup checks are pending, go into fallback mode - // immediately. This short-circuits the timeout for the fallback-at-startup - // case. - if (grpclb_policy->fallback_at_startup_checks_pending_) { - GPR_ASSERT(!lb_calld->seen_serverlist_); + // If we did not receive a serverlist and the fallback-at-startup checks + // are pending, go into fallback mode immediately. This short-circuits + // the timeout for the fallback-at-startup case. + if (!lb_calld->seen_serverlist_ && + grpclb_policy->fallback_at_startup_checks_pending_) { gpr_log(GPR_INFO, - "[grpclb %p] Balancer call finished without receiving " + "[grpclb %p] balancer call finished without receiving " "serverlist; entering fallback mode", grpclb_policy); grpclb_policy->fallback_at_startup_checks_pending_ = false; @@ -1393,7 +1394,6 @@ void GrpcLb::UpdateLocked(UpdateArgs args) { } else { child_policy_config_ = nullptr; } - ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); // Update the existing child policy. if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); @@ -1627,16 +1627,20 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked( bool is_backend_from_grpclb_load_balancer) { - InlinedVector args_to_add; - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer)); + grpc_arg args_to_add[2] = { + // A channel arg indicating if the target is a backend inferred from a + // grpclb load balancer. + grpc_channel_arg_integer_create( + const_cast( + GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), + is_backend_from_grpclb_load_balancer), + }; + size_t num_args_to_add = 1; if (is_backend_from_grpclb_load_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); + args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); } - return grpc_channel_args_copy_and_add(args_, args_to_add.data(), - args_to_add.size()); + return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add); } OrphanablePtr GrpcLb::CreateChildPolicyLocked( @@ -1830,8 +1834,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { return RefCountedPtr( New(std::move(child_policy))); } else { - *error = - ServiceConfig::CreateErrorFromVector("GrpcLb Parser", &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list); return nullptr; } } diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index b25f66d1dfc..a71efa1f230 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -362,10 +362,9 @@ class XdsLb : public LoadBalancingPolicy { : parent_(std::move(parent)), locality_weight_(locality_weight) {} ~LocalityEntry() = default; - void UpdateLocked( - xds_grpclb_serverlist* serverlist, - const RefCountedPtr& child_policy_config, - const grpc_channel_args* args); + void UpdateLocked(xds_grpclb_serverlist* serverlist, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args); void ShutdownLocked(); void ResetBackoffLocked(); void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -410,10 +409,9 @@ class XdsLb : public LoadBalancingPolicy { uint32_t locality_weight_; }; - void UpdateLocked( - const LocalityList& locality_list, - const RefCountedPtr& child_policy_config, - const grpc_channel_args* args, XdsLb* parent); + void UpdateLocked(const LocalityList& locality_list, + ParsedLoadBalancingConfig* child_policy_config, + const grpc_channel_args* args, XdsLb* parent); void ShutdownLocked(); void ResetBackoffLocked(); void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, @@ -1217,7 +1215,7 @@ void XdsLb::BalancerChannelState::BalancerCallState:: xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; xdslb_policy->locality_map_.UpdateLocked( xdslb_policy->locality_serverlist_, - xdslb_policy->child_policy_config_, xdslb_policy->args_, + xdslb_policy->child_policy_config_.get(), xdslb_policy->args_, xdslb_policy); } } else { @@ -1530,8 +1528,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) { return; } ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); - locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, args_, - this); + locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(), + args_, this); // Update the existing fallback policy. The fallback policy config and/or the // fallback addresses may be new. if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked(); @@ -1750,7 +1748,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) { void XdsLb::LocalityMap::UpdateLocked( const LocalityList& locality_serverlist, - const RefCountedPtr& child_policy_config, + ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args, XdsLb* parent) { if (parent->shutting_down_) return; for (size_t i = 0; i < locality_serverlist.size(); i++) { @@ -1845,13 +1843,13 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( xds_grpclb_serverlist* serverlist, - const RefCountedPtr& child_policy_config, + ParsedLoadBalancingConfig* child_policy_config, const grpc_channel_args* args_in) { if (parent_->shutting_down_) return; // Construct update args. UpdateArgs update_args; update_args.addresses = ProcessServerlist(serverlist); - update_args.config = child_policy_config; + update_args.config = child_policy_config->Ref(); update_args.args = CreateChildPolicyArgsLocked(args_in); // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store @@ -2176,8 +2174,8 @@ class XdsFactory : public LoadBalancingPolicyFactory { InlinedVector error_list; const char* balancer_name = nullptr; - RefCountedPtr child_policy = nullptr; - RefCountedPtr fallback_policy = nullptr; + RefCountedPtr child_policy; + RefCountedPtr fallback_policy; for (const grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) continue; @@ -2229,7 +2227,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { return RefCountedPtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); } else { - *error = ServiceConfig::CreateErrorFromVector("Xds Parser", &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Xds Parser", &error_list); return nullptr; } } diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc index b9ea97d4051..973aa26d0f6 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.cc +++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc @@ -94,9 +94,21 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( return factory->CreateLoadBalancingPolicy(std::move(args)); } -bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { +bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + const char* name, bool* requires_config) { GPR_ASSERT(g_state != nullptr); - return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; + auto* factory = g_state->GetLoadBalancingPolicyFactory(name); + if (factory == nullptr) { + return false; + } + if (requires_config != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; + // Check if the load balancing policy allows an empty config + *requires_config = + factory->ParseLoadBalancingConfig(nullptr, &error) == nullptr; + GRPC_ERROR_UNREF(error); + } + return true; } namespace { @@ -152,7 +164,8 @@ grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array, return nullptr; } // If we support this policy, then select it. - if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { + if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key, + nullptr)) { return policy; } } @@ -189,19 +202,4 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json, } } -grpc_error* LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( - const char* lb_policy_name) { - GPR_DEBUG_ASSERT(g_state != nullptr); - gpr_log(GPR_ERROR, "%s", lb_policy_name); - auto* factory = g_state->GetLoadBalancingPolicyFactory(lb_policy_name); - if (factory == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:loadBalancingPolicy error:Unknown lb policy"); - } - grpc_error* error = GRPC_ERROR_NONE; - // Check if the load balancing policy allows an empty config - factory->ParseLoadBalancingConfig(nullptr, &error); - return error; -} - } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h index 7fa52914cd9..6820cfc9334 100644 --- a/src/core/ext/filters/client_channel/lb_policy_registry.h +++ b/src/core/ext/filters/client_channel/lb_policy_registry.h @@ -49,16 +49,15 @@ class LoadBalancingPolicyRegistry { const char* name, LoadBalancingPolicy::Args args); /// Returns true if the LB policy factory specified by \a name exists in this - /// registry. - static bool LoadBalancingPolicyExists(const char* name); + /// registry. If the load balancing policy requires a config to be specified + /// then sets \a requires_config to true. + static bool LoadBalancingPolicyExists(const char* name, + bool* requires_config); /// Returns a parsed object of the load balancing policy to be used from a /// LoadBalancingConfig array \a json. static RefCountedPtr ParseLoadBalancingConfig( const grpc_json* json, grpc_error** error); - - /// Validates if a load balancing policy can be created from \a lb_policy_name - static grpc_error* CanCreateLoadBalancingPolicy(const char* lb_policy_name); }; } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index a3bb6b9969b..82fe3c71a5f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -29,7 +29,6 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" @@ -88,25 +87,13 @@ ProcessedResolverResult::ProcessedResolverResult( void ProcessedResolverResult::ProcessServiceConfig( const Resolver::Result& resolver_result, const ClientChannelGlobalParsedObject* parsed_object) { - auto* health_check = static_cast( - service_config_->GetParsedGlobalServiceConfigObject( - HealthCheckParser::ParserIndex())); - health_check_service_name_ = - health_check != nullptr ? health_check->service_name() : nullptr; + health_check_service_name_ = parsed_object->health_check_service_name(); service_config_json_ = service_config_->service_config_json(); if (!parsed_object) { return; } if (parsed_object->retry_throttling().has_value()) { - const grpc_arg* channel_arg = - grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI); - const char* server_uri = grpc_channel_arg_get_string(channel_arg); - GPR_ASSERT(server_uri != nullptr); - grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); - server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path; retry_throttle_data_ = parsed_object->retry_throttling(); - grpc_uri_destroy(uri); } } @@ -122,12 +109,6 @@ void ProcessedResolverResult::ProcessLbPolicy( } else { lb_policy_name_.reset( gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); - if (lb_policy_name_ != nullptr) { - char* lb_policy_name = lb_policy_name_.get(); - for (size_t i = 0; i < strlen(lb_policy_name); ++i) { - lb_policy_name[i] = tolower(lb_policy_name[i]); - } - } } } // Otherwise, find the LB policy name set by the client API. @@ -215,8 +196,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->max_attempts != 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxAttempts error:Duplicate entry")); - continue; - } // Duplicate. + } // Duplicate. Continue Parsing if (sub_field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxAttempts error:should be of type number")); @@ -238,8 +218,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->initial_backoff > 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:initialBackoff error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:initialBackoff error:Failed to parse")); @@ -253,8 +232,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->max_backoff > 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxBackoff error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxBackoff error:failed to parse")); @@ -268,8 +246,7 @@ UniquePtr ParseRetryPolicy( if (retry_policy->backoff_multiplier != 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:backoffMultiplier error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (sub_field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:backoffMultiplier error:should be of type number")); @@ -289,8 +266,7 @@ UniquePtr ParseRetryPolicy( if (!retry_policy->retryable_status_codes.Empty()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryableStatusCodes error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (sub_field->type != GRPC_JSON_ARRAY) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryableStatusCodes error:should be of type array")); @@ -329,10 +305,48 @@ UniquePtr ParseRetryPolicy( return nullptr; } } - *error = ServiceConfig::CreateErrorFromVector("retryPolicy", &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list); return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; } +const char* ParseHealthCheckConfig(const grpc_json* field, grpc_error** error) { + GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); + const char* service_name = nullptr; + GPR_DEBUG_ASSERT(strcmp(field->key, "healthCheckConfig") == 0); + if (field->type != GRPC_JSON_OBJECT) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:should be of type object"); + return nullptr; + } + InlinedVector error_list; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) { + GPR_DEBUG_ASSERT(false); + continue; + } + if (strcmp(sub_field->key, "serviceName") == 0) { + if (service_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:Duplicate " + "entry")); + } // Duplicate. Continue parsing + if (sub_field->type != GRPC_JSON_STRING) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:serviceName error:should be of type string")); + continue; + } + service_name = sub_field->value; + } + } + if (!error_list.empty()) { + return nullptr; + } + *error = + GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list); + return service_name; +} + } // namespace UniquePtr @@ -343,6 +357,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, RefCountedPtr parsed_lb_config; UniquePtr lb_policy_name; Optional retry_throttling; + const char* health_check_service_name = nullptr; for (grpc_json* field = json->child; field != nullptr; field = field->next) { if (field->key == nullptr) { continue; // Not the LB config global parameter @@ -352,14 +367,12 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, if (parsed_lb_config != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingConfig error:Duplicate entry")); - } else { - grpc_error* parse_error = GRPC_ERROR_NONE; - parsed_lb_config = - LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, - &parse_error); - if (parsed_lb_config == nullptr) { - error_list.push_back(parse_error); - } + } // Duplicate, continue parsing. + grpc_error* parse_error = GRPC_ERROR_NONE; + parsed_lb_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( + field, &parse_error); + if (parsed_lb_config == nullptr) { + error_list.push_back(parse_error); } } // Parse deprecated loadBalancingPolicy @@ -367,8 +380,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, if (lb_policy_name != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Duplicate entry")); - continue; - } else if (field->type != GRPC_JSON_STRING) { + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_STRING) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:type should be string")); continue; @@ -380,126 +393,141 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, lb_policy[i] = tolower(lb_policy[i]); } } - if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(lb_policy)) { + bool requires_config = false; + if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( + lb_policy, &requires_config)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); - } else { - grpc_error* parsing_error = - LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( - lb_policy); - if (parsing_error != GRPC_ERROR_NONE) { - error_list.push_back(parsing_error); - } + } else if (requires_config) { + char* error_msg; + gpr_asprintf(&error_msg, + "field:loadBalancingPolicy error:%s requires a config. " + "Please use loadBalancingConfig instead.", + lb_policy); + error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg)); + gpr_free(error_msg); } } // Parse retry throttling if (strcmp(field->key, "retryThrottling") == 0) { + if (retry_throttling.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling error:Duplicate entry")); + } // Duplicate, continue parsing. if (field->type != GRPC_JSON_OBJECT) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling error:Type should be object")); - } else if (retry_throttling.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling error:Duplicate entry")); - } else { - Optional max_milli_tokens; - Optional milli_token_ratio; - for (grpc_json* sub_field = field->child; sub_field != nullptr; - sub_field = sub_field->next) { - if (sub_field->key == nullptr) continue; - if (strcmp(sub_field->key, "maxTokens") == 0) { - if (max_milli_tokens.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:Duplicate " - "entry")); - } else if (sub_field->type != GRPC_JSON_NUMBER) { + continue; + } + Optional max_milli_tokens; + Optional milli_token_ratio; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) continue; + if (strcmp(sub_field->key, "maxTokens") == 0) { + if (max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Duplicate " + "entry")); + } else if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Type should be " + "number")); + } else { + max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * + 1000); + if (max_milli_tokens.value() <= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:Type should be " - "number")); - } else { - max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) * - 1000); - if (max_milli_tokens.value() <= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:should be " - "greater than zero")); - } + "field:retryThrottling field:maxTokens error:should be " + "greater than zero")); } - } else if (strcmp(sub_field->key, "tokenRatio") == 0) { - if (milli_token_ratio.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:Duplicate " - "entry")); - } else if (sub_field->type != GRPC_JSON_NUMBER) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:type should be " - "number")); - } else { - // We support up to 3 decimal digits. - size_t whole_len = strlen(sub_field->value); - uint32_t multiplier = 1; - uint32_t decimal_value = 0; - const char* decimal_point = strchr(sub_field->value, '.'); - if (decimal_point != nullptr) { - whole_len = - static_cast(decimal_point - sub_field->value); - multiplier = 1000; - size_t decimal_len = strlen(decimal_point + 1); - if (decimal_len > 3) decimal_len = 3; - if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, - &decimal_value)) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:Failed " - "parsing")); - continue; - } - uint32_t decimal_multiplier = 1; - for (size_t i = 0; i < (3 - decimal_len); ++i) { - decimal_multiplier *= 10; - } - decimal_value *= decimal_multiplier; - } - uint32_t whole_value; - if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, - &whole_value)) { + } + } else if (strcmp(sub_field->key, "tokenRatio") == 0) { + if (milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Duplicate " + "entry")); + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:type should be " + "number")); + } else { + // We support up to 3 decimal digits. + size_t whole_len = strlen(sub_field->value); + uint32_t multiplier = 1; + uint32_t decimal_value = 0; + const char* decimal_point = strchr(sub_field->value, '.'); + if (decimal_point != nullptr) { + whole_len = static_cast(decimal_point - sub_field->value); + multiplier = 1000; + size_t decimal_len = strlen(decimal_point + 1); + if (decimal_len > 3) decimal_len = 3; + if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, + &decimal_value)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:tokenRatio error:Failed " "parsing")); continue; } - milli_token_ratio.set( - static_cast((whole_value * multiplier) + decimal_value)); - if (milli_token_ratio.value() <= 0) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:value should " - "be greater than 0")); + uint32_t decimal_multiplier = 1; + for (size_t i = 0; i < (3 - decimal_len); ++i) { + decimal_multiplier *= 10; } + decimal_value *= decimal_multiplier; + } + uint32_t whole_value; + if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len, + &whole_value)) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Failed " + "parsing")); + continue; + } + milli_token_ratio.set( + static_cast((whole_value * multiplier) + decimal_value)); + if (milli_token_ratio.value() <= 0) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:value should " + "be greater than 0")); } } } - if (!max_milli_tokens.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:maxTokens error:Not found")); - } - if (!milli_token_ratio.has_value()) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:retryThrottling field:tokenRatio error:Not found")); - } - if (error_list.size() == 0) { - ClientChannelGlobalParsedObject::RetryThrottling data; - data.max_milli_tokens = max_milli_tokens.value(); - data.milli_token_ratio = milli_token_ratio.value(); - retry_throttling.set(data); - } + } + if (!max_milli_tokens.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:maxTokens error:Not found")); + } + if (!milli_token_ratio.has_value()) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:retryThrottling field:tokenRatio error:Not found")); + } + if (error_list.size() == 0) { + ClientChannelGlobalParsedObject::RetryThrottling data; + data.max_milli_tokens = max_milli_tokens.value(); + data.milli_token_ratio = milli_token_ratio.value(); + retry_throttling.set(data); + } + } + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (health_check_service_name != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:healthCheckConfig error:Duplicate entry")); + } // Duplicate continue parsing + grpc_error* parsing_error = GRPC_ERROR_NONE; + health_check_service_name = ParseHealthCheckConfig(field, &parsing_error); + if (parsing_error != GRPC_ERROR_NONE) { + error_list.push_back(parsing_error); } } } - *error = ServiceConfig::CreateErrorFromVector("Client channel global parser", - &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser", + &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( - New(std::move(parsed_lb_config), - std::move(lb_policy_name), - retry_throttling)); + New( + std::move(parsed_lb_config), std::move(lb_policy_name), + retry_throttling, health_check_service_name)); } return nullptr; } @@ -518,8 +546,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, if (wait_for_ready.has_value()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:waitForReady error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (field->type == GRPC_JSON_TRUE) { wait_for_ready.set(true); } else if (field->type == GRPC_JSON_FALSE) { @@ -532,8 +559,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, if (timeout > 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:timeout error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. if (!ParseDuration(field, &timeout)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:timeout error:Failed parsing")); @@ -542,8 +568,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, if (retry_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryPolicy error:Duplicate entry")); - continue; - } + } // Duplicate, continue parsing. grpc_error* error = GRPC_ERROR_NONE; retry_policy = ParseRetryPolicy(field, &error); if (retry_policy == nullptr) { @@ -551,8 +576,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, } } } - *error = ServiceConfig::CreateErrorFromVector("Client channel parser", - &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list); if (*error == GRPC_ERROR_NONE) { return UniquePtr( New(timeout, wait_for_ready, diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 25830dd4642..1a49fa7be8e 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -47,10 +47,12 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { ClientChannelGlobalParsedObject( RefCountedPtr parsed_lb_config, UniquePtr parsed_deprecated_lb_policy, - const Optional& retry_throttling) + const Optional& retry_throttling, + const char* health_check_service_name) : parsed_lb_config_(std::move(parsed_lb_config)), parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)), - retry_throttling_(retry_throttling) {} + retry_throttling_(retry_throttling), + health_check_service_name_(health_check_service_name) {} Optional retry_throttling() const { return retry_throttling_; @@ -64,10 +66,15 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { return parsed_deprecated_lb_policy_.get(); } + const char* health_check_service_name() const { + return health_check_service_name_; + } + private: RefCountedPtr parsed_lb_config_; UniquePtr parsed_deprecated_lb_policy_; Optional retry_throttling_; + const char* health_check_service_name_ = nullptr; }; class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { @@ -111,8 +118,9 @@ class ClientChannelServiceConfigParser : public ServiceConfig::Parser { static void Register(); }; -// A container of processed fields from the resolver result. Simplifies the -// usage of resolver result. +// TODO(yashykt): It would be cleaner to move this logic to the client_channel +// code. A container of processed fields from the resolver result. Simplifies +// the usage of resolver result. class ProcessedResolverResult { public: // Processes the resolver result and populates the relative members @@ -122,21 +130,19 @@ class ProcessedResolverResult { // Getters. Any managed object's ownership is transferred. const char* service_config_json() { return service_config_json_; } - const char* server_name() { return server_name_; } - - Optional - retry_throttle_data() { - return retry_throttle_data_; - } + RefCountedPtr service_config() { return service_config_; } UniquePtr lb_policy_name() { return std::move(lb_policy_name_); } RefCountedPtr lb_policy_config() { return lb_policy_config_; } - const char* health_check_service_name() { return health_check_service_name_; } + Optional + retry_throttle_data() { + return retry_throttle_data_; + } - RefCountedPtr service_config() { return service_config_; } + const char* health_check_service_name() { return health_check_service_name_; } private: // Finds the service config; extracts LB config and (maybe) retry throttle @@ -163,9 +169,8 @@ class ProcessedResolverResult { RefCountedPtr service_config_; // LB policy. UniquePtr lb_policy_name_; - RefCountedPtr lb_policy_config_ = nullptr; + RefCountedPtr lb_policy_config_; // Retry throttle data. - const char* server_name_ = nullptr; Optional retry_throttle_data_; const char* health_check_service_name_ = nullptr; diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.cc b/src/core/ext/filters/client_channel/resolving_lb_policy.cc index 79d8cf43bc9..193c9e256ed 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.cc +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.cc @@ -530,7 +530,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked( const bool resolution_contains_addresses = result.addresses.size() > 0; // Process the resolver result. const char* lb_policy_name = nullptr; - RefCountedPtr lb_policy_config = nullptr; + RefCountedPtr lb_policy_config; bool service_config_changed = false; if (process_resolver_result_ != nullptr) { service_config_changed = diff --git a/src/core/ext/filters/client_channel/resolving_lb_policy.h b/src/core/ext/filters/client_channel/resolving_lb_policy.h index 9822c2d1dc2..dd8a1de6c7a 100644 --- a/src/core/ext/filters/client_channel/resolving_lb_policy.h +++ b/src/core/ext/filters/client_channel/resolving_lb_policy.h @@ -123,7 +123,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy { ProcessResolverResultCallback process_resolver_result_ = nullptr; void* process_resolver_result_user_data_ = nullptr; UniquePtr child_policy_name_; - RefCountedPtr child_lb_config_ = nullptr; + RefCountedPtr child_lb_config_; // Resolver and associated state. OrphanablePtr resolver_; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 8db3df712e6..86d4f7368c0 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -98,7 +98,7 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) { } parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); } - return CreateErrorFromVector("Global Params", &error_list); + return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list); } grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( @@ -154,7 +154,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( ++*idx; } wrap_error: - return CreateErrorFromVector("methodConfig", &error_list); + return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list); } grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { @@ -211,7 +211,7 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { num_entries, entries, nullptr); gpr_free(entries); } - return CreateErrorFromVector("Method Params", &error_list); + return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list); } ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } @@ -313,7 +313,7 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) { return *value; } -size_t ServiceConfig::RegisterParser(UniquePtr parser) { +size_t ServiceConfig::RegisterParser(UniquePtr parser) { g_registered_parsers->push_back(std::move(parser)); return g_registered_parsers->size() - 1; } diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 1372b50eb2a..e6f855ad934 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -71,14 +71,14 @@ class ServiceConfig : public RefCounted { public: virtual ~Parser() = default; - virtual UniquePtr ParseGlobalParams( - const grpc_json* json, grpc_error** error) { + virtual UniquePtr ParseGlobalParams(const grpc_json* json, + grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr); return nullptr; } - virtual UniquePtr ParsePerMethodParams( - const grpc_json* json, grpc_error** error) { + virtual UniquePtr ParsePerMethodParams(const grpc_json* json, + grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr); return nullptr; } @@ -87,10 +87,14 @@ class ServiceConfig : public RefCounted { }; static constexpr int kNumPreallocatedParsers = 4; - typedef InlinedVector, - kNumPreallocatedParsers> + typedef InlinedVector, kNumPreallocatedParsers> ServiceConfigObjectsVector; + /// When a service config is applied to a call in the client_channel_filter, + /// we create an instance of this object and store it in the call_data for + /// client_channel. A pointer to this object is also stored in the + /// call_context, so that future filters can easily access method and global + /// parameters for the call. class CallData { public: CallData() = default; @@ -102,20 +106,21 @@ class ServiceConfig : public RefCounted { } } - RefCountedPtr service_config() { return service_config_; } + ServiceConfig* service_config() { return service_config_.get(); } - ServiceConfig::ParsedConfig* GetMethodParsedObject(int index) const { + ParsedConfig* GetMethodParsedObject(size_t index) const { return method_params_vector_ != nullptr ? (*method_params_vector_)[index].get() : nullptr; } - bool empty() const { return service_config_ == nullptr; } + ParsedConfig* GetGlobalParsedObject(size_t index) const { + return service_config_->GetParsedGlobalServiceConfigObject(index); + } private: RefCountedPtr service_config_; - const ServiceConfig::ServiceConfigObjectsVector* method_params_vector_ = - nullptr; + const ServiceConfigObjectsVector* method_params_vector_ = nullptr; }; /// Creates a new service config from parsing \a json_string. @@ -130,8 +135,7 @@ class ServiceConfig : public RefCounted { /// Retrieves the parsed global service config object at index \a index. The /// lifetime of the returned object is tied to the lifetime of the /// ServiceConfig object. - ServiceConfig::ParsedConfig* GetParsedGlobalServiceConfigObject( - size_t index) { + ParsedConfig* GetParsedGlobalServiceConfigObject(size_t index) { GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); return parsed_global_service_config_objects_[index].get(); } @@ -148,30 +152,12 @@ class ServiceConfig : public RefCounted { /// registered parser. Each parser is responsible for reading the service /// config json and returning a parsed object. This parsed object can later be /// retrieved using the same index that was returned at registration time. - static size_t RegisterParser(UniquePtr parser); + static size_t RegisterParser(UniquePtr parser); static void Init(); static void Shutdown(); - // Consumes all the errors in the vector and forms a referencing error from - // them. If the vector is empty, return GRPC_ERROR_NONE. - template - static grpc_error* CreateErrorFromVector( - const char* desc, InlinedVector* error_list) { - grpc_error* error = GRPC_ERROR_NONE; - if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); - // Remove refs to all errors in error_list. - for (size_t i = 0; i < error_list->size(); i++) { - GRPC_ERROR_UNREF((*error_list)[i]); - } - error_list->clear(); - } - return error; - } - private: // So New() can call our private ctor. template @@ -203,7 +189,7 @@ class ServiceConfig : public RefCounted { UniquePtr json_string_; // Underlying storage for json_tree. grpc_json* json_tree_; - InlinedVector, kNumPreallocatedParsers> + InlinedVector, kNumPreallocatedParsers> parsed_global_service_config_objects_; // A map from the method name to the service config objects vector. Note that // we are using a raw pointer and not a unique pointer so that we can use the diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index e9140a7b1c0..a92fc0e2991 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -38,12 +38,12 @@ static void recv_message_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); +namespace grpc_core { + namespace { size_t g_message_size_parser_index; } // namespace -namespace grpc_core { - UniquePtr MessageSizeParser::ParsePerMethodParams( const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); @@ -56,8 +56,8 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_request_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { + } // Duplicate, continue parsing. + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxRequestMessageBytes error:should be of type number")); } else { @@ -71,8 +71,8 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); - } else if (field->type != GRPC_JSON_STRING && - field->type != GRPC_JSON_NUMBER) { + } // Duplicate, conitnue parsing + if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:should be of type number")); } else { @@ -85,8 +85,7 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( } } if (!error_list.empty()) { - *error = ServiceConfig::CreateErrorFromVector("Message size parser", - &error_list); + *error = GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list); return nullptr; } return UniquePtr(New( @@ -332,7 +331,12 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, channel_data* chand = static_cast(elem->channel_data); new (chand) channel_data(); chand->limits = get_message_size_limits(args->channel_args); - // Get method config table from channel args. + // TODO(yashykt): We only need to read GRPC_ARG_SERVICE_CONFIG in the case of + // direct channels. (Service config is otherwise stored in the call_context by + // client_channel filter.) If we ever need a second filter that also needs to + // parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a + // separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed + // config in the call_context. Get service config from channel args. const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); const char* service_config_str = grpc_channel_arg_get_string(channel_arg); diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 5bead0c88ee..2166fe4763a 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,7 +26,7 @@ namespace grpc_core { template class Optional { public: - Optional() { value_ = {}; } + Optional() { value_ = T(); } void set(const T& val) { value_ = val; set_ = true; diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index fcc6f0761b3..a877f499fb1 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -30,6 +30,7 @@ #include #include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/inlined_vector.h" /// Opaque representation of an error. /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a @@ -193,6 +194,24 @@ inline void grpc_error_unref(grpc_error* err) { #define GRPC_ERROR_UNREF(err) grpc_error_unref(err) #endif +// Consumes all the errors in the vector and forms a referencing error from +// them. If the vector is empty, return GRPC_ERROR_NONE. +template +static grpc_error* GRPC_ERROR_CREATE_FROM_VECTOR( + const char* desc, grpc_core::InlinedVector* error_list) { + grpc_error* error = GRPC_ERROR_NONE; + if (error_list->size() != 0) { + error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + desc, error_list->data(), error_list->size()); + // Remove refs to all errors in error_list. + for (size_t i = 0; i < error_list->size(); i++) { + GRPC_ERROR_UNREF((*error_list)[i]); + } + error_list->clear(); + } + return error; +} + grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, intptr_t value) GRPC_MUST_USE_RESULT; /// It is an error to pass nullptr as `p`. Caller should allocate a dummy diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 8060b5a0a8c..12a47e71d7e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc', - 'src/core/ext/filters/client_channel/health/health_check_parser.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 7a41283012e..9734304c9ac 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -21,7 +21,6 @@ #include #include -#include "src/core/ext/filters/client_channel/health/health_check_parser.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/message_size/message_size_filter.h" @@ -528,13 +527,13 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { auto svc_cfg = ServiceConfig::Create(test_json, &error); gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:loadBalancingPolicy error:Xds " - "Parser has required field - balancerName. Please use " - "loadBalancingConfig field of service config instead.)")); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(Client channel global " + "parser)(.*)(referenced_errors)(.*)(field:" + "loadBalancingPolicy error:xds_experimental requires a " + "config. Please use loadBalancingConfig instead.)")); VerifyRegexMatch(error, e); } @@ -856,7 +855,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { " \"retryPolicy\": {\n" " \"maxAttempts\": 1,\n" " \"initialBackoff\": \"1s\",\n" - " \"maxBackoff\": \"120sec\",\n" + " \"maxBackoff\": \"120s\",\n" " \"backoffMultiplier\": \"1.6\",\n" " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" " }\n" @@ -886,7 +885,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { " \"retryPolicy\": {\n" " \"maxAttempts\": 1,\n" " \"initialBackoff\": \"1s\",\n" - " \"maxBackoff\": \"120sec\",\n" + " \"maxBackoff\": \"120s\",\n" " \"backoffMultiplier\": \"1.6\",\n" " \"retryableStatusCodes\": []\n" " }\n" @@ -906,6 +905,50 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { VerifyRegexMatch(error, e); } +TEST_F(ClientChannelParserTest, ValidHealthCheck) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_TRUE(error == GRPC_ERROR_NONE); + const auto* parsed_object = + static_cast( + svc_cfg->GetParsedGlobalServiceConfigObject(0)); + ASSERT_TRUE(parsed_object != nullptr); + EXPECT_EQ(strcmp(parsed_object->health_check_service_name(), + "health_check_service_name"), + 0); +} + +TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { + const char* test_json = + "{\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name\"\n" + " },\n" + " \"healthCheckConfig\": {\n" + " \"serviceName\": \"health_check_service_name1\"\n" + " }\n" + "}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); + ASSERT_TRUE(error != GRPC_ERROR_NONE); + std::regex e( + std::string("(Service config parsing " + "error)(.*)(referenced_errors)(.*)(Global " + "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig " + "error:Duplicate entry)")); + std::smatch match; + std::string s(grpc_error_string(error)); + EXPECT_TRUE(std::regex_search(s, match, e)); + GRPC_ERROR_UNREF(error); +} + class MessageSizeParserTest : public ::testing::Test { protected: void SetUp() override { @@ -989,59 +1032,6 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { VerifyRegexMatch(error, e); } -class HealthCheckParserTest : public ::testing::Test { - protected: - void SetUp() override { - ServiceConfig::Shutdown(); - ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr( - New())) == 0); - } -}; - -TEST_F(HealthCheckParserTest, Valid) { - const char* test_json = - "{\n" - " \"healthCheckConfig\": {\n" - " \"serviceName\": \"health_check_service_name\"\n" - " }\n" - "}"; - grpc_error* error = GRPC_ERROR_NONE; - auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); - const auto* parsed_object = static_cast( - svc_cfg->GetParsedGlobalServiceConfigObject(0)); - ASSERT_TRUE(parsed_object != nullptr); - EXPECT_EQ(strcmp(parsed_object->service_name(), "health_check_service_name"), - 0); -} - -TEST_F(HealthCheckParserTest, MultipleEntries) { - const char* test_json = - "{\n" - " \"healthCheckConfig\": {\n" - " \"serviceName\": \"health_check_service_name\"\n" - " },\n" - " \"healthCheckConfig\": {\n" - " \"serviceName\": \"health_check_service_name1\"\n" - " }\n" - "}"; - grpc_error* error = GRPC_ERROR_NONE; - auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(field:healthCheckConfig)(" - ".*)(referenced_errors)(.*)" - "(field:serviceName error:Duplicate entry)")); - std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); - GRPC_ERROR_UNREF(error); -} - } // namespace testing } // namespace grpc_core diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index eee3f777ea6..dad6c98269d 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -892,8 +892,6 @@ src/core/ext/filters/client_channel/health/health.pb.c \ src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.h \ -src/core/ext/filters/client_channel/health/health_check_parser.cc \ -src/core/ext/filters/client_channel/health/health_check_parser.h \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.h \ src/core/ext/filters/client_channel/http_proxy.cc \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 0c2204a3f79..9b9ad7d430c 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -8732,7 +8732,6 @@ "src/core/ext/filters/client_channel/connector.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.h", - "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", @@ -8773,8 +8772,6 @@ "src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.h", - "src/core/ext/filters/client_channel/health/health_check_parser.cc", - "src/core/ext/filters/client_channel/health/health_check_parser.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.cc", From 1214dff100aca0705855495798c473c78ac22000 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Thu, 25 Apr 2019 17:00:00 -0700 Subject: [PATCH 077/112] Clean up --- .../health/health_check_parser.h | 52 ------------------- .../client_channel/lb_policy/grpclb/grpclb.cc | 13 +++-- .../client_channel/lb_policy/xds/xds.cc | 6 +-- .../message_size/message_size_filter.cc | 2 +- 4 files changed, 9 insertions(+), 64 deletions(-) delete mode 100644 src/core/ext/filters/client_channel/health/health_check_parser.h diff --git a/src/core/ext/filters/client_channel/health/health_check_parser.h b/src/core/ext/filters/client_channel/health/health_check_parser.h deleted file mode 100644 index 0143f147152..00000000000 --- a/src/core/ext/filters/client_channel/health/health_check_parser.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2019 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H - -#include - -#include "src/core/ext/filters/client_channel/service_config.h" - -namespace grpc_core { -#if 0 -class HealthCheckParsedObject : public ServiceConfig::ParsedConfig { - public: - HealthCheckParsedObject(const char* service_name) - : service_name_(service_name) {} - - // Returns the service_name found in the health check config. The lifetime of - // the string is tied to the lifetime of the ServiceConfig object. - const char* service_name() const { return service_name_; } - - private: - const char* service_name_; -}; - -class HealthCheckParser : public ServiceConfig::Parser { - public: - UniquePtr ParseGlobalParams( - const grpc_json* json, grpc_error** error) override; - - static void Register(); - - static size_t ParserIndex(); -}; -#endif -} // namespace grpc_core -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 4bf4dc0ac0b..0bcd471f52f 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1143,13 +1143,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // we want to retry connecting. Otherwise, we have deliberately ended this // call and no further action is required. if (lb_calld == grpclb_policy->lb_calld_.get()) { - // If we did not receive a serverlist and the fallback-at-startup checks - // are pending, go into fallback mode immediately. This short-circuits - // the timeout for the fallback-at-startup case. - if (!lb_calld->seen_serverlist_ && - grpclb_policy->fallback_at_startup_checks_pending_) { + // If the fallback-at-startup checks are pending, go into fallback mode + // immediately. This short-circuits the timeout for the fallback-at-startup + // case. + if (grpclb_policy->fallback_at_startup_checks_pending_) { + GPR_ASSERT(!lb_calld->seen_serverlist_); gpr_log(GPR_INFO, - "[grpclb %p] balancer call finished without receiving " + "[grpclb %p] Balancer call finished without receiving " "serverlist; entering fallback mode", grpclb_policy); grpclb_policy->fallback_at_startup_checks_pending_ = false; @@ -1820,7 +1820,6 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory { if (child_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:childPolicy error:Duplicate entry")); - continue; } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index a71efa1f230..f3806bdbde1 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1849,7 +1849,8 @@ void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( // Construct update args. UpdateArgs update_args; update_args.addresses = ProcessServerlist(serverlist); - update_args.config = child_policy_config->Ref(); + update_args.config = + child_policy_config == nullptr ? nullptr : child_policy_config->Ref(); update_args.args = CreateChildPolicyArgsLocked(args_in); // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store @@ -2183,7 +2184,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (balancer_name != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:balancerName error:Duplicate entry")); - continue; } if (field->type != GRPC_JSON_STRING) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -2195,7 +2195,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (child_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:childPolicy error:Duplicate entry")); - continue; } grpc_error* parse_error = GRPC_ERROR_NONE; child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( @@ -2208,7 +2207,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { if (fallback_policy != nullptr) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:fallbackPolicy error:Duplicate entry")); - continue; } grpc_error* parse_error = GRPC_ERROR_NONE; fallback_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig( diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index a92fc0e2991..d21ecb901ac 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -336,7 +336,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem, // client_channel filter.) If we ever need a second filter that also needs to // parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a // separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed - // config in the call_context. Get service config from channel args. + // config in the call_context. const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); const char* service_config_str = grpc_channel_arg_get_string(channel_arg); From 488e649781bb2a7cdc32dbbf7ac6dbbbded31793 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 26 Apr 2019 07:45:00 +0200 Subject: [PATCH 078/112] Add info about C# nightly nuget feed --- src/csharp/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/csharp/README.md b/src/csharp/README.md index 291772ff939..391671b34a8 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -40,6 +40,17 @@ See [Experimentally supported platforms](experimental) for instructions. See [Experimentally supported platforms](experimental) for instructions. +NUGET DEVELOPMENT FEED (NIGHTLY BUILDS) +-------------- + +In production, you should use officially released stable packages available on http://nuget.org, but if you want to test the newest upstream bug fixes and features early, you can can use the development nuget feed where new nuget builds are uploaded nightly. + +Feed URL (NuGet v2): https://grpc.jfrog.io/grpc/api/nuget/grpc-nuget-dev + +Feed URL (NuGet v3): Feed https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev + +The same development nuget packages and packages for other languages can also be found at https://packages.grpc.io/ + BUILD FROM SOURCE ----------------- From a96f2e860ce5ebcc283f6a830872676dceae7abd Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Fri, 26 Apr 2019 08:15:56 +0200 Subject: [PATCH 079/112] fix a nit Co-Authored-By: jtattermusch --- src/csharp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/README.md b/src/csharp/README.md index 391671b34a8..c01cae0422d 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -47,7 +47,7 @@ In production, you should use officially released stable packages available on h Feed URL (NuGet v2): https://grpc.jfrog.io/grpc/api/nuget/grpc-nuget-dev -Feed URL (NuGet v3): Feed https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev +Feed URL (NuGet v3): https://grpc.jfrog.io/grpc/api/nuget/v3/grpc-nuget-dev The same development nuget packages and packages for other languages can also be found at https://packages.grpc.io/ From c864bea0c675d7abe67978c8f263c76d6a411875 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 23 Apr 2019 17:58:44 -0700 Subject: [PATCH 080/112] Move TestService to a separate file to simplify its dependency --- .../tests/fork/_fork_interop_test.py | 4 +- .../grpcio_tests/tests/interop/BUILD.bazel | 87 +++++++++-------- .../tests/interop/_insecure_intraop_test.py | 4 +- .../tests/interop/_secure_intraop_test.py | 4 +- .../grpcio_tests/tests/interop/methods.py | 73 -------------- .../grpcio_tests/tests/interop/server.py | 4 +- .../grpcio_tests/tests/interop/service.py | 97 +++++++++++++++++++ 7 files changed, 154 insertions(+), 119 deletions(-) create mode 100644 src/python/grpcio_tests/tests/interop/service.py diff --git a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py index 608148dfe46..602786c5e0d 100644 --- a/src/python/grpcio_tests/tests/fork/_fork_interop_test.py +++ b/src/python/grpcio_tests/tests/fork/_fork_interop_test.py @@ -56,12 +56,12 @@ class ForkInteropTest(unittest.TestCase): import grpc from src.proto.grpc.testing import test_pb2_grpc - from tests.interop import methods as interop_methods + from tests.interop import service as interop_service from tests.unit import test_common server = test_common.test_server() test_pb2_grpc.add_TestServiceServicer_to_server( - interop_methods.TestService(), server) + interop_service.TestService(), server) port = server.add_insecure_port('[::]:0') server.start() print(port) diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel index 770b1f78a70..fd636556074 100644 --- a/src/python/grpcio_tests/tests/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel @@ -5,45 +5,45 @@ package(default_visibility = ["//visibility:public"]) py_library( name = "_intraop_test_case", srcs = ["_intraop_test_case.py"], + imports = ["../../"], deps = [ ":methods", ], - imports=["../../",], ) py_library( name = "client", srcs = ["client.py"], + imports = ["../../"], deps = [ - "//src/python/grpcio/grpc:grpcio", ":methods", ":resources", "//src/proto/grpc/testing:py_test_proto", - requirement('google-auth'), + "//src/python/grpcio/grpc:grpcio", + requirement("google-auth"), ], - imports=["../../",], ) py_library( name = "methods", srcs = ["methods.py"], + imports = ["../../"], deps = [ "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_tests/tests:bazel_namespace_package_hack", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:py_test_proto", - requirement('google-auth'), - requirement('requests'), - requirement('urllib3'), - requirement('chardet'), - requirement('certifi'), - requirement('idna'), + requirement("google-auth"), + requirement("requests"), + requirement("urllib3"), + requirement("chardet"), + requirement("certifi"), + requirement("idna"), ] + select({ - "//conditions:default": [requirement('enum34'),], + "//conditions:default": [requirement("enum34")], "//:python3": [], }), - imports=["../../",], ) py_library( @@ -54,51 +54,62 @@ py_library( ], ) +py_library( + name = "service", + srcs = ["service.py"], + imports = ["../../"], + deps = [ + "//src/proto/grpc/testing:py_empty_proto", + "//src/proto/grpc/testing:py_messages_proto", + "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + ], +) + py_library( name = "server", srcs = ["server.py"], + imports = ["../../"], deps = [ - "//src/python/grpcio/grpc:grpcio", - ":methods", ":resources", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], - imports=["../../",], ) py_test( - name="_insecure_intraop_test", - size="small", - srcs=["_insecure_intraop_test.py",], - main="_insecure_intraop_test.py", - deps=[ - "//src/python/grpcio/grpc:grpcio", + name = "_insecure_intraop_test", + size = "small", + srcs = ["_insecure_intraop_test.py"], + data = [ + "//src/python/grpcio_tests/tests/unit/credentials", + ], + imports = ["../../"], + main = "_insecure_intraop_test.py", + deps = [ ":_intraop_test_case", - ":methods", ":server", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", - ], - imports=["../../",], - data=[ - "//src/python/grpcio_tests/tests/unit/credentials", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], ) py_test( - name="_secure_intraop_test", - size="small", - srcs=["_secure_intraop_test.py",], - main="_secure_intraop_test.py", - deps=[ - "//src/python/grpcio/grpc:grpcio", + name = "_secure_intraop_test", + size = "small", + srcs = ["_secure_intraop_test.py"], + imports = ["../../"], + main = "_secure_intraop_test.py", + deps = [ ":_intraop_test_case", - ":methods", ":server", - "//src/python/grpcio_tests/tests/unit:test_common", + ":service", "//src/proto/grpc/testing:py_test_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", ], - imports=["../../",], ) - diff --git a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py index ace15bea585..fecf31767a7 100644 --- a/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py +++ b/src/python/grpcio_tests/tests/interop/_insecure_intraop_test.py @@ -19,7 +19,7 @@ import grpc from src.proto.grpc.testing import test_pb2_grpc from tests.interop import _intraop_test_case -from tests.interop import methods +from tests.interop import service from tests.interop import server from tests.unit import test_common @@ -29,7 +29,7 @@ class InsecureIntraopTest(_intraop_test_case.IntraopTestCase, def setUp(self): self.server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), self.server) port = self.server.add_insecure_port('[::]:0') self.server.start() diff --git a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py index e27e551ecb0..1b5e5cfd2dd 100644 --- a/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py +++ b/src/python/grpcio_tests/tests/interop/_secure_intraop_test.py @@ -19,7 +19,7 @@ import grpc from src.proto.grpc.testing import test_pb2_grpc from tests.interop import _intraop_test_case -from tests.interop import methods +from tests.interop import service from tests.interop import resources from tests.unit import test_common @@ -30,7 +30,7 @@ class SecureIntraopTest(_intraop_test_case.IntraopTestCase, unittest.TestCase): def setUp(self): self.server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), self.server) port = self.server.add_secure_port( '[::]:0', diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 08d8901a6b4..250db8bb385 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -35,82 +35,9 @@ import grpc from src.proto.grpc.testing import empty_pb2 from src.proto.grpc.testing import messages_pb2 -from src.proto.grpc.testing import test_pb2_grpc _INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" _TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" -_US_IN_A_SECOND = 1000 * 1000 - - -def _maybe_echo_metadata(servicer_context): - """Copies metadata from request to response if it is present.""" - invocation_metadata = dict(servicer_context.invocation_metadata()) - if _INITIAL_METADATA_KEY in invocation_metadata: - initial_metadatum = (_INITIAL_METADATA_KEY, - invocation_metadata[_INITIAL_METADATA_KEY]) - servicer_context.send_initial_metadata((initial_metadatum,)) - if _TRAILING_METADATA_KEY in invocation_metadata: - trailing_metadatum = (_TRAILING_METADATA_KEY, - invocation_metadata[_TRAILING_METADATA_KEY]) - servicer_context.set_trailing_metadata((trailing_metadatum,)) - - -def _maybe_echo_status_and_message(request, servicer_context): - """Sets the response context code and details if the request asks for them""" - if request.HasField('response_status'): - servicer_context.set_code(request.response_status.code) - servicer_context.set_details(request.response_status.message) - - -class TestService(test_pb2_grpc.TestServiceServicer): - - def EmptyCall(self, request, context): - _maybe_echo_metadata(context) - return empty_pb2.Empty() - - def UnaryCall(self, request, context): - _maybe_echo_metadata(context) - _maybe_echo_status_and_message(request, context) - return messages_pb2.SimpleResponse( - payload=messages_pb2.Payload( - type=messages_pb2.COMPRESSABLE, - body=b'\x00' * request.response_size)) - - def StreamingOutputCall(self, request, context): - _maybe_echo_status_and_message(request, context) - for response_parameters in request.response_parameters: - if response_parameters.interval_us != 0: - time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) - yield messages_pb2.StreamingOutputCallResponse( - payload=messages_pb2.Payload( - type=request.response_type, - body=b'\x00' * response_parameters.size)) - - def StreamingInputCall(self, request_iterator, context): - aggregate_size = 0 - for request in request_iterator: - if request.payload is not None and request.payload.body: - aggregate_size += len(request.payload.body) - return messages_pb2.StreamingInputCallResponse( - aggregated_payload_size=aggregate_size) - - def FullDuplexCall(self, request_iterator, context): - _maybe_echo_metadata(context) - for request in request_iterator: - _maybe_echo_status_and_message(request, context) - for response_parameters in request.response_parameters: - if response_parameters.interval_us != 0: - time.sleep( - response_parameters.interval_us / _US_IN_A_SECOND) - yield messages_pb2.StreamingOutputCallResponse( - payload=messages_pb2.Payload( - type=request.payload.type, - body=b'\x00' * response_parameters.size)) - - # NOTE(nathaniel): Apparently this is the same as the full-duplex call? - # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... - def HalfDuplexCall(self, request_iterator, context): - return self.FullDuplexCall(request_iterator, context) def _expect_status_code(call, expected_code): diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index 72f88a1c989..3611ffdbb2f 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -21,7 +21,7 @@ import time import grpc from src.proto.grpc.testing import test_pb2_grpc -from tests.interop import methods +from tests.interop import service from tests.interop import resources from tests.unit import test_common @@ -42,7 +42,7 @@ def serve(): args = parser.parse_args() server = test_common.test_server() - test_pb2_grpc.add_TestServiceServicer_to_server(methods.TestService(), + test_pb2_grpc.add_TestServiceServicer_to_server(service.TestService(), server) if args.use_tls: private_key = resources.private_key() diff --git a/src/python/grpcio_tests/tests/interop/service.py b/src/python/grpcio_tests/tests/interop/service.py new file mode 100644 index 00000000000..20f76fceebf --- /dev/null +++ b/src/python/grpcio_tests/tests/interop/service.py @@ -0,0 +1,97 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""The Python implementation of the TestServicer.""" + +import time + +import grpc + +from src.proto.grpc.testing import empty_pb2 +from src.proto.grpc.testing import messages_pb2 +from src.proto.grpc.testing import test_pb2_grpc + +_INITIAL_METADATA_KEY = "x-grpc-test-echo-initial" +_TRAILING_METADATA_KEY = "x-grpc-test-echo-trailing-bin" +_US_IN_A_SECOND = 1000 * 1000 + + +def _maybe_echo_metadata(servicer_context): + """Copies metadata from request to response if it is present.""" + invocation_metadata = dict(servicer_context.invocation_metadata()) + if _INITIAL_METADATA_KEY in invocation_metadata: + initial_metadatum = (_INITIAL_METADATA_KEY, + invocation_metadata[_INITIAL_METADATA_KEY]) + servicer_context.send_initial_metadata((initial_metadatum,)) + if _TRAILING_METADATA_KEY in invocation_metadata: + trailing_metadatum = (_TRAILING_METADATA_KEY, + invocation_metadata[_TRAILING_METADATA_KEY]) + servicer_context.set_trailing_metadata((trailing_metadatum,)) + + +def _maybe_echo_status_and_message(request, servicer_context): + """Sets the response context code and details if the request asks for them""" + if request.HasField('response_status'): + servicer_context.set_code(request.response_status.code) + servicer_context.set_details(request.response_status.message) + + +class TestService(test_pb2_grpc.TestServiceServicer): + + def EmptyCall(self, request, context): + _maybe_echo_metadata(context) + return empty_pb2.Empty() + + def UnaryCall(self, request, context): + _maybe_echo_metadata(context) + _maybe_echo_status_and_message(request, context) + return messages_pb2.SimpleResponse( + payload=messages_pb2.Payload( + type=messages_pb2.COMPRESSABLE, + body=b'\x00' * request.response_size)) + + def StreamingOutputCall(self, request, context): + _maybe_echo_status_and_message(request, context) + for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep(response_parameters.interval_us / _US_IN_A_SECOND) + yield messages_pb2.StreamingOutputCallResponse( + payload=messages_pb2.Payload( + type=request.response_type, + body=b'\x00' * response_parameters.size)) + + def StreamingInputCall(self, request_iterator, context): + aggregate_size = 0 + for request in request_iterator: + if request.payload is not None and request.payload.body: + aggregate_size += len(request.payload.body) + return messages_pb2.StreamingInputCallResponse( + aggregated_payload_size=aggregate_size) + + def FullDuplexCall(self, request_iterator, context): + _maybe_echo_metadata(context) + for request in request_iterator: + _maybe_echo_status_and_message(request, context) + for response_parameters in request.response_parameters: + if response_parameters.interval_us != 0: + time.sleep( + response_parameters.interval_us / _US_IN_A_SECOND) + yield messages_pb2.StreamingOutputCallResponse( + payload=messages_pb2.Payload( + type=request.payload.type, + body=b'\x00' * response_parameters.size)) + + # NOTE(nathaniel): Apparently this is the same as the full-duplex call? + # NOTE(atash): It isn't even called in the interop spec (Oct 22 2015)... + def HalfDuplexCall(self, request_iterator, context): + return self.FullDuplexCall(request_iterator, context) \ No newline at end of file From 73dbdccc5d2422867793d59a55c432051eee94b2 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 11:42:48 -0700 Subject: [PATCH 081/112] Reviewer comments and cleanup --- .../filters/client_channel/client_channel.cc | 1 + .../client_channel/lb_policy/grpclb/grpclb.cc | 20 ++++++++----------- .../client_channel/resolver_result_parsing.cc | 8 +++----- .../client_channel/resolver_result_parsing.h | 2 +- .../message_size/message_size_filter.cc | 2 +- src/core/lib/iomgr/error.h | 12 +++++++---- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index f0bc3417a2b..26a9e59be08 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1070,6 +1070,7 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) GPR_ASSERT(uri->path[0] != '\0'); server_name_.reset( gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + grpc_uri_destroy(uri); char* proxy_name = nullptr; grpc_channel_args* new_args = nullptr; grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 0bcd471f52f..e28a1495c18 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1627,20 +1627,16 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) { grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked( bool is_backend_from_grpclb_load_balancer) { - grpc_arg args_to_add[2] = { - // A channel arg indicating if the target is a backend inferred from a - // grpclb load balancer. - grpc_channel_arg_integer_create( - const_cast( - GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), - is_backend_from_grpclb_load_balancer), - }; - size_t num_args_to_add = 1; + InlinedVector args_to_add; + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), + is_backend_from_grpclb_load_balancer)); if (is_backend_from_grpclb_load_balancer) { - args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + args_to_add.emplace_back(grpc_channel_arg_integer_create( + const_cast(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); } - return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add); + return grpc_channel_args_copy_and_add(args_, args_to_add.data(), + args_to_add.size()); } OrphanablePtr GrpcLb::CreateChildPolicyLocked( diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 82fe3c71a5f..418c4deae9a 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -89,10 +89,7 @@ void ProcessedResolverResult::ProcessServiceConfig( const ClientChannelGlobalParsedObject* parsed_object) { health_check_service_name_ = parsed_object->health_check_service_name(); service_config_json_ = service_config_->service_config_json(); - if (!parsed_object) { - return; - } - if (parsed_object->retry_throttling().has_value()) { + if (parsed_object != nullptr) { retry_throttle_data_ = parsed_object->retry_throttling(); } } @@ -429,7 +426,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:maxTokens error:Duplicate " "entry")); - } else if (sub_field->type != GRPC_JSON_NUMBER) { + } // Duplicate, continue parsing. + if (sub_field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:maxTokens error:Type should be " "number")); diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 1a49fa7be8e..e44482419ae 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -173,7 +173,7 @@ class ProcessedResolverResult { // Retry throttle data. Optional retry_throttle_data_; - const char* health_check_service_name_ = nullptr; + const char* health_check_service_name_; }; } // namespace internal diff --git a/src/core/ext/filters/message_size/message_size_filter.cc b/src/core/ext/filters/message_size/message_size_filter.cc index d21ecb901ac..a973cbca121 100644 --- a/src/core/ext/filters/message_size/message_size_filter.cc +++ b/src/core/ext/filters/message_size/message_size_filter.cc @@ -71,7 +71,7 @@ UniquePtr MessageSizeParser::ParsePerMethodParams( if (max_response_message_bytes >= 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:Duplicate entry")); - } // Duplicate, conitnue parsing + } // Duplicate, continue parsing if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:maxResponseMessageBytes error:should be of type number")); diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index a877f499fb1..7b04888e9ec 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -166,6 +166,9 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_error_create(__FILE__, __LINE__, grpc_slice_from_copied_string(desc), \ errs, count) +#define GRPC_ERROR_CREATE_FROM_VECTOR(desc, error_list) \ + grpc_error_create_from_vector(__FILE__, __LINE__, desc, error_list) + #ifndef NDEBUG grpc_error* grpc_error_do_ref(grpc_error* err, const char* file, int line); void grpc_error_do_unref(grpc_error* err, const char* file, int line); @@ -197,12 +200,13 @@ inline void grpc_error_unref(grpc_error* err) { // Consumes all the errors in the vector and forms a referencing error from // them. If the vector is empty, return GRPC_ERROR_NONE. template -static grpc_error* GRPC_ERROR_CREATE_FROM_VECTOR( - const char* desc, grpc_core::InlinedVector* error_list) { +static grpc_error* grpc_error_create_from_vector( + const char* file, int line, const char* desc, + grpc_core::InlinedVector* error_list) { grpc_error* error = GRPC_ERROR_NONE; if (error_list->size() != 0) { - error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( - desc, error_list->data(), error_list->size()); + error = grpc_error_create(file, line, grpc_slice_from_static_string(desc), + error_list->data(), error_list->size()); // Remove refs to all errors in error_list. for (size_t i = 0; i < error_list->size(); i++) { GRPC_ERROR_UNREF((*error_list)[i]); From 019272d3ad792d27fd5256c657fea4512a4d3e7d Mon Sep 17 00:00:00 2001 From: Prashant Jaikumar Date: Fri, 26 Apr 2019 11:51:02 -0700 Subject: [PATCH 082/112] Revert "Objective C should use error codes defined by C core" This reverts commit 2d5468e8263cfdb0595dfd36fba9df6f7c63075a. --- src/objective-c/GRPCClient/GRPCCall.h | 33 +++++++++---------- src/objective-c/ProtoRPC/ProtoRPC.m | 3 +- src/objective-c/tests/APIv2Tests/APIv2Tests.m | 2 +- src/objective-c/tests/InteropTests.m | 21 ++++++------ src/objective-c/tests/UnitTests/UnitTests.m | 6 ++-- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h index 852fc81fefe..6669067fbff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.h +++ b/src/objective-c/GRPCClient/GRPCCall.h @@ -34,7 +34,6 @@ #import #import -#include #include @@ -54,20 +53,20 @@ extern NSString *const kGRPCErrorDomain; */ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { /** The operation was cancelled (typically by the caller). */ - GRPCErrorCodeCancelled = GRPC_STATUS_CANCELLED, + GRPCErrorCodeCancelled = 1, /** * Unknown error. Errors raised by APIs that do not return enough error information may be * converted to this error. */ - GRPCErrorCodeUnknown = GRPC_STATUS_UNKNOWN, + GRPCErrorCodeUnknown = 2, /** * The client specified an invalid argument. Note that this differs from FAILED_PRECONDITION. * INVALID_ARGUMENT indicates arguments that are problematic regardless of the state of the * server (e.g., a malformed file name). */ - GRPCErrorCodeInvalidArgument = GRPC_STATUS_INVALID_ARGUMENT, + GRPCErrorCodeInvalidArgument = 3, /** * Deadline expired before operation could complete. For operations that change the state of the @@ -75,13 +74,13 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * example, a successful response from the server could have been delayed long enough for the * deadline to expire. */ - GRPCErrorCodeDeadlineExceeded = GRPC_STATUS_DEADLINE_EXCEEDED, + GRPCErrorCodeDeadlineExceeded = 4, /** Some requested entity (e.g., file or directory) was not found. */ - GRPCErrorCodeNotFound = GRPC_STATUS_NOT_FOUND, + GRPCErrorCodeNotFound = 5, /** Some entity that we attempted to create (e.g., file or directory) already exists. */ - GRPCErrorCodeAlreadyExists = GRPC_STATUS_ALREADY_EXISTS, + GRPCErrorCodeAlreadyExists = 6, /** * The caller does not have permission to execute the specified operation. PERMISSION_DENIED isn't @@ -89,16 +88,16 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * those errors). PERMISSION_DENIED doesn't indicate a failure to identify the caller * (UNAUTHENTICATED is used instead for those errors). */ - GRPCErrorCodePermissionDenied = GRPC_STATUS_PERMISSION_DENIED, + GRPCErrorCodePermissionDenied = 7, /** * The request does not have valid authentication credentials for the operation (e.g. the caller's * identity can't be verified). */ - GRPCErrorCodeUnauthenticated = GRPC_STATUS_UNAUTHENTICATED, + GRPCErrorCodeUnauthenticated = 16, /** Some resource has been exhausted, perhaps a per-user quota. */ - GRPCErrorCodeResourceExhausted = GRPC_STATUS_RESOURCE_EXHAUSTED, + GRPCErrorCodeResourceExhausted = 8, /** * The RPC was rejected because the server is not in a state required for the procedure's @@ -107,14 +106,14 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * performing another RPC). The details depend on the service being called, and should be found in * the NSError's userInfo. */ - GRPCErrorCodeFailedPrecondition = GRPC_STATUS_FAILED_PRECONDITION, + GRPCErrorCodeFailedPrecondition = 9, /** * The RPC was aborted, typically due to a concurrency issue like sequencer check failures, * transaction aborts, etc. The client should retry at a higher-level (e.g., restarting a read- * modify-write sequence). */ - GRPCErrorCodeAborted = GRPC_STATUS_ABORTED, + GRPCErrorCodeAborted = 10, /** * The RPC was attempted past the valid range. E.g., enumerating past the end of a list. @@ -123,25 +122,25 @@ typedef NS_ENUM(NSUInteger, GRPCErrorCode) { * to return the element at a negative index, but it will generate OUT_OF_RANGE if asked to return * the element at an index past the current size of the list. */ - GRPCErrorCodeOutOfRange = GRPC_STATUS_OUT_OF_RANGE, + GRPCErrorCodeOutOfRange = 11, /** The procedure is not implemented or not supported/enabled in this server. */ - GRPCErrorCodeUnimplemented = GRPC_STATUS_UNIMPLEMENTED, + GRPCErrorCodeUnimplemented = 12, /** * Internal error. Means some invariant expected by the server application or the gRPC library has * been broken. */ - GRPCErrorCodeInternal = GRPC_STATUS_INTERNAL, + GRPCErrorCodeInternal = 13, /** * The server is currently unavailable. This is most likely a transient condition and may be * corrected by retrying with a backoff. */ - GRPCErrorCodeUnavailable = GRPC_STATUS_UNAVAILABLE, + GRPCErrorCodeUnavailable = 14, /** Unrecoverable data loss or corruption. */ - GRPCErrorCodeDataLoss = GRPC_STATUS_DATA_LOSS, + GRPCErrorCodeDataLoss = 15, }; /** diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index bc5d721fe41..0ab96a5ba2b 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -41,7 +41,8 @@ static NSError *ErrorForBadProto(id proto, Class expectedClass, NSError *parsing @"Expected class" : expectedClass, @"Received value" : proto, }; - return [NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeInternal userInfo:info]; + // TODO(jcanizales): Use kGRPCErrorDomain and GRPCErrorCodeInternal when they're public. + return [NSError errorWithDomain:@"io.grpc" code:13 userInfo:info]; } @implementation GRPCUnaryProtoCall { diff --git a/src/objective-c/tests/APIv2Tests/APIv2Tests.m b/src/objective-c/tests/APIv2Tests/APIv2Tests.m index 67951e6c589..ea777e27812 100644 --- a/src/objective-c/tests/APIv2Tests/APIv2Tests.m +++ b/src/objective-c/tests/APIv2Tests/APIv2Tests.m @@ -151,7 +151,7 @@ static const NSTimeInterval kTestTimeout = 16; closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { trailing_md = trailingMetadata; if (error) { - XCTAssertEqual(error.code, GRPCErrorCodeUnauthenticated, + XCTAssertEqual(error.code, 16, @"Finished with unexpected error: %@", error); XCTAssertEqualObjects(init_md, error.userInfo[kGRPCHeadersKey]); diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 22cc41eb93c..0d2c409f6f3 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -355,9 +355,9 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; if (i % 3 == 0) { - request.responseStatus.code = GRPCErrorCodeUnavailable; + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; } else if (i % 7 == 0) { - request.responseStatus.code = GRPCErrorCodeCancelled; + request.responseStatus.code = GRPC_STATUS_CANCELLED; } GRPCMutableCallOptions *options = [[GRPCMutableCallOptions alloc] init]; options.transportType = [[self class] transportType]; @@ -404,9 +404,9 @@ BOOL isRemoteInteropTest(NSString *host) { request.responseSize = 314159; request.payload.body = [NSMutableData dataWithLength:271828]; if (i % 3 == 0) { - request.responseStatus.code = GRPCErrorCodeUnavailable; + request.responseStatus.code = GRPC_STATUS_UNAVAILABLE; } else if (i % 7 == 0) { - request.responseStatus.code = GRPCErrorCodeCancelled; + request.responseStatus.code = GRPC_STATUS_CANCELLED; } [_service unaryCallWithRequest:request @@ -726,7 +726,7 @@ BOOL isRemoteInteropTest(NSString *host) { RPCToStreamingInputCallWithRequestsWriter:requestsBuffer handler:^(RMTStreamingInputCallResponse *response, NSError *error) { - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [expectation fulfill]; }]; XCTAssertEqual(call.state, GRXWriterStateNotStarted); @@ -754,8 +754,7 @@ BOOL isRemoteInteropTest(NSString *host) { } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertEqual(error.code, - GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [expectation fulfill]; }] callOptions:nil]; @@ -786,7 +785,7 @@ BOOL isRemoteInteropTest(NSString *host) { NSError *error) { if (receivedResponse) { XCTAssert(done, @"Unexpected extra response %@", response); - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [expectation fulfill]; } else { XCTAssertNil(error, @"Finished with unexpected error: %@", @@ -829,7 +828,7 @@ BOOL isRemoteInteropTest(NSString *host) { } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [completionExpectation fulfill]; }] callOptions:options]; @@ -859,7 +858,7 @@ BOOL isRemoteInteropTest(NSString *host) { } closeCallback:^(NSDictionary *trailingMetadata, NSError *error) { - XCTAssertEqual(error.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED); [completionExpectation fulfill]; }] callOptions:options]; @@ -960,7 +959,7 @@ BOOL isRemoteInteropTest(NSString *host) { } else { // Keepalive should kick after 1s elapsed and fails the call. XCTAssertNotNil(error); - XCTAssertEqual(error.code, GRPCErrorCodeUnavailable); + XCTAssertEqual(error.code, GRPC_STATUS_UNAVAILABLE); XCTAssertEqualObjects( error.localizedDescription, @"keepalive watchdog timeout", @"Unexpected failure that is not keepalive watchdog timeout."); diff --git a/src/objective-c/tests/UnitTests/UnitTests.m b/src/objective-c/tests/UnitTests/UnitTests.m index ea3d56db68d..4dcb8c08d28 100644 --- a/src/objective-c/tests/UnitTests/UnitTests.m +++ b/src/objective-c/tests/UnitTests/UnitTests.m @@ -42,18 +42,18 @@ [NSError grpc_errorFromStatusCode:GRPC_STATUS_UNAVAILABLE details:nil errorString:nil]; XCTAssertNil(error1); - XCTAssertEqual(error2.code, GRPCErrorCodeCancelled); + XCTAssertEqual(error2.code, 1); XCTAssertEqualObjects(error2.domain, @"io.grpc"); XCTAssertEqualObjects(error2.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); XCTAssertEqualObjects(error2.userInfo[NSDebugDescriptionErrorKey], [NSString stringWithUTF8String:kErrorString]); - XCTAssertEqual(error3.code, GRPCErrorCodeUnauthenticated); + XCTAssertEqual(error3.code, 16); XCTAssertEqualObjects(error3.domain, @"io.grpc"); XCTAssertEqualObjects(error3.userInfo[NSLocalizedDescriptionKey], [NSString stringWithUTF8String:kDetails]); XCTAssertNil(error3.userInfo[NSDebugDescriptionErrorKey]); - XCTAssertEqual(error4.code, GRPCErrorCodeUnavailable); + XCTAssertEqual(error4.code, 14); XCTAssertEqualObjects(error4.domain, @"io.grpc"); XCTAssertNil(error4.userInfo[NSLocalizedDescriptionKey]); XCTAssertNil(error4.userInfo[NSDebugDescriptionErrorKey]); From d3035a3d5f7a1441807b1d114ee4d269133776a3 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 12:38:36 -0700 Subject: [PATCH 083/112] Revert changes to optional --- .../client_channel/resolver_result_parsing.cc | 16 ++++++++-------- .../client_channel/resolver_result_parsing.h | 4 ++-- src/core/lib/gprpp/optional.h | 1 - 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 418c4deae9a..35e54779c69 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -416,8 +416,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, "field:retryThrottling error:Type should be object")); continue; } - Optional max_milli_tokens; - Optional milli_token_ratio; + Optional max_milli_tokens = Optional(); + Optional milli_token_ratio = Optional(); for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; @@ -492,20 +492,20 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, } } } + ClientChannelGlobalParsedObject::RetryThrottling data; if (!max_milli_tokens.has_value()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:maxTokens error:Not found")); + } else { + data.max_milli_tokens = max_milli_tokens.value(); } if (!milli_token_ratio.has_value()) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:retryThrottling field:tokenRatio error:Not found")); - } - if (error_list.size() == 0) { - ClientChannelGlobalParsedObject::RetryThrottling data; - data.max_milli_tokens = max_milli_tokens.value(); + } else { data.milli_token_ratio = milli_token_ratio.value(); - retry_throttling.set(data); } + retry_throttling.set(data); } if (strcmp(field->key, "healthCheckConfig") == 0) { if (health_check_service_name != nullptr) { @@ -535,7 +535,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; - Optional wait_for_ready; + Optional wait_for_ready = Optional(); grpc_millis timeout = 0; UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index e44482419ae..7307149496f 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -74,7 +74,7 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig { RefCountedPtr parsed_lb_config_; UniquePtr parsed_deprecated_lb_policy_; Optional retry_throttling_; - const char* health_check_service_name_ = nullptr; + const char* health_check_service_name_; }; class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { @@ -173,7 +173,7 @@ class ProcessedResolverResult { // Retry throttle data. Optional retry_throttle_data_; - const char* health_check_service_name_; + const char* health_check_service_name_ = nullptr; }; } // namespace internal diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 2166fe4763a..87d336ad6d0 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,7 +26,6 @@ namespace grpc_core { template class Optional { public: - Optional() { value_ = T(); } void set(const T& val) { value_ = val; set_ = true; From 5f6a57a4d00080e611873f5e13517eeb1647fb85 Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Fri, 26 Apr 2019 12:49:06 -0700 Subject: [PATCH 084/112] Formatting issues --- include/grpcpp/create_channel.h | 2 +- include/grpcpp/create_channel_impl.h | 14 +++++++------- include/grpcpp/impl/codegen/client_context.h | 2 +- include/grpcpp/impl/server_builder_plugin.h | 2 +- include/grpcpp/security/credentials.h | 6 +++++- include/grpcpp/security/credentials_impl.h | 5 ++--- include/grpcpp/support/channel_arguments.h | 3 ++- include/grpcpp/support/channel_arguments_impl.h | 1 + src/cpp/client/create_channel_posix.cc | 2 ++ src/cpp/client/cronet_credentials.cc | 3 +-- src/cpp/client/insecure_credentials.cc | 6 +++--- src/cpp/client/secure_credentials.cc | 2 +- src/cpp/client/secure_credentials.h | 6 +++--- 13 files changed, 30 insertions(+), 24 deletions(-) diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h index e7336cb2adf..9b257ace945 100644 --- a/include/grpcpp/create_channel.h +++ b/include/grpcpp/create_channel.h @@ -32,7 +32,7 @@ static inline std::shared_ptr<::grpc::Channel> CreateChannel( static inline std::shared_ptr<::grpc::Channel> CreateCustomChannel( const grpc::string& target, - const std::shared_ptr& creds, + const std::shared_ptr& creds, const ChannelArguments& args) { return ::grpc_impl::CreateCustomChannelImpl(target, creds, args); } diff --git a/include/grpcpp/create_channel_impl.h b/include/grpcpp/create_channel_impl.h index 84dd2f7c765..ebf8b96973e 100644 --- a/include/grpcpp/create_channel_impl.h +++ b/include/grpcpp/create_channel_impl.h @@ -35,9 +35,9 @@ namespace grpc_impl { /// \param creds Credentials to use for the created channel. If it does not /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. -std::shared_ptr CreateChannelImpl( +std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, - const std::shared_ptr& creds); + const std::shared_ptr<::grpc::ChannelCredentials>& creds); /// Create a new \em custom \a Channel pointing to \a target. /// @@ -49,10 +49,10 @@ std::shared_ptr CreateChannelImpl( /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelImpl( +std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( const grpc::string& target, - const std::shared_ptr& creds, - const grpc::ChannelArguments& args); + const std::shared_ptr<::grpc::ChannelCredentials>& creds, + const ::grpc::ChannelArguments& args); namespace experimental { /// Create a new \em custom \a Channel pointing to \a target with \a @@ -66,10 +66,10 @@ namespace experimental { /// hold an object or is invalid, a lame channel (one on which all operations /// fail) is returned. /// \param args Options for channel creation. -std::shared_ptr CreateCustomChannelWithInterceptors( +std::shared_ptr<::grpc::Channel> CreateCustomChannelWithInterceptors( const grpc::string& target, const std::shared_ptr& creds, - const grpc::ChannelArguments& args, + const ::grpc::ChannelArguments& args, std::vector< std::unique_ptr> interceptor_creators); diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h index 7326648b46f..355ac557b3a 100644 --- a/include/grpcpp/impl/codegen/client_context.h +++ b/include/grpcpp/impl/codegen/client_context.h @@ -60,7 +60,7 @@ struct grpc_call; namespace grpc_impl { class CallCredentials; -} +} // namespace grpc_impl namespace grpc { class Channel; diff --git a/include/grpcpp/impl/server_builder_plugin.h b/include/grpcpp/impl/server_builder_plugin.h index 8bac36e5651..84a88f2dd7b 100644 --- a/include/grpcpp/impl/server_builder_plugin.h +++ b/include/grpcpp/impl/server_builder_plugin.h @@ -26,8 +26,8 @@ namespace grpc_impl { class ChannelArguments; -class ServerInitializer; class ServerBuilder; +class ServerInitializer; } // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h index 5eb77096bd0..e924275d592 100644 --- a/include/grpcpp/security/credentials.h +++ b/include/grpcpp/security/credentials.h @@ -44,10 +44,14 @@ GoogleComputeEngineCredentials() { return ::grpc_impl::GoogleComputeEngineCredentials(); } +/// Constant for maximum auth token lifetime. +constexpr long kMaxAuthTokenLifetimeSecs = + ::grpc_impl::kMaxAuthTokenLifetimeSecs; + static inline std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = ::grpc_impl::kMaxAuthTokenLifetimeSecs) { + long token_lifetime_seconds = grpc::kMaxAuthTokenLifetimeSecs) { return ::grpc_impl::ServiceAccountJWTAccessCredentials( json_key, token_lifetime_seconds); } diff --git a/include/grpcpp/security/credentials_impl.h b/include/grpcpp/security/credentials_impl.h index 19017093dd5..536d4b07688 100644 --- a/include/grpcpp/security/credentials_impl.h +++ b/include/grpcpp/security/credentials_impl.h @@ -41,7 +41,7 @@ class CallCredentials; class SecureCallCredentials; class SecureChannelCredentials; -std::shared_ptr<::grpc::Channel> CreateCustomChannel( +std::shared_ptr<::grpc::Channel> CreateCustomChannelImpl( const grpc::string& target, const std::shared_ptr& creds, const grpc::ChannelArguments& args); @@ -171,7 +171,6 @@ std::shared_ptr SslCredentials( /// services. std::shared_ptr GoogleComputeEngineCredentials(); -/// Constant for maximum auth token lifetime. constexpr long kMaxAuthTokenLifetimeSecs = 3600; /// Builds Service Account JWT Access credentials. @@ -181,7 +180,7 @@ constexpr long kMaxAuthTokenLifetimeSecs = 3600; /// \a kMaxAuthTokenLifetimeSecs or will be cropped to this value. std::shared_ptr ServiceAccountJWTAccessCredentials( const grpc::string& json_key, - long token_lifetime_seconds = kMaxAuthTokenLifetimeSecs); + long token_lifetime_seconds = grpc_impl::kMaxAuthTokenLifetimeSecs); /// Builds refresh token credentials. /// json_refresh_token is the JSON string containing the refresh token along diff --git a/include/grpcpp/support/channel_arguments.h b/include/grpcpp/support/channel_arguments.h index 24700f56fbd..593aaec76a7 100644 --- a/include/grpcpp/support/channel_arguments.h +++ b/include/grpcpp/support/channel_arguments.h @@ -23,8 +23,9 @@ namespace grpc_impl { +class SecureChannelCredentials; class ResourceQuota; -} +} // namespace grpc_impl namespace grpc { diff --git a/include/grpcpp/support/channel_arguments_impl.h b/include/grpcpp/support/channel_arguments_impl.h index db85e9b07ad..0efeadca880 100644 --- a/include/grpcpp/support/channel_arguments_impl.h +++ b/include/grpcpp/support/channel_arguments_impl.h @@ -34,6 +34,7 @@ class ChannelArgumentsTest; } // namespace grpc namespace grpc_impl { + class SecureChannelCredentials; /// Options for channel creation. The user can use generic setters to pass diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc index 54b7148865b..61260a27c66 100644 --- a/src/cpp/client/create_channel_posix.cc +++ b/src/cpp/client/create_channel_posix.cc @@ -26,6 +26,8 @@ namespace grpc_impl { +class ChannelArguments; + #ifdef GPR_SUPPORT_CHANNELS_FROM_FD std::shared_ptr CreateInsecureChannelFromFd( diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc index 89ae9e7e9ce..f4ead14cde8 100644 --- a/src/cpp/client/cronet_credentials.cc +++ b/src/cpp/client/cronet_credentials.cc @@ -57,8 +57,7 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials { }; } // namespace grpc namespace grpc_impl { -std::shared_ptr CronetChannelCredentials( - void* engine) { +std::shared_ptr CronetChannelCredentials(void* engine) { return std::shared_ptr( new grpc::CronetChannelCredentialsImpl(engine)); } diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 3a6b1aa6e05..dcbb56dccda 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,7 +31,7 @@ namespace grpc_impl { namespace { class InsecureChannelCredentialsImpl final : public ChannelCredentials { public: - std::shared_ptr CreateChannelImpl( + std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) override { return CreateChannelWithInterceptors( target, args, @@ -39,14 +39,14 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials { grpc::experimental::ClientInterceptorFactoryInterface>>()); } - std::shared_ptr CreateChannelWithInterceptors( + std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> interceptor_creators) override { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return grpc::CreateChannelInternal( + return ::grpc::CreateChannelInternal( "", grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr), std::move(interceptor_creators)); diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 71ad5a73c3b..724a43a9709 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -50,7 +50,7 @@ SecureChannelCredentials::CreateChannelWithInterceptors( interceptor_creators) { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return grpc::CreateChannelInternal( + return ::grpc::CreateChannelInternal( args.GetSslTargetNameOverride(), grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args, nullptr), diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h index 1dc083fa0cf..cc18172558d 100644 --- a/src/cpp/client/secure_credentials.h +++ b/src/cpp/client/secure_credentials.h @@ -37,16 +37,16 @@ class SecureChannelCredentials final : public ChannelCredentials { } grpc_channel_credentials* GetRawCreds() { return c_creds_; } - std::shared_ptr CreateChannelImpl( + std::shared_ptr<::grpc::Channel> CreateChannelImpl( const grpc::string& target, const grpc::ChannelArguments& args) override; SecureChannelCredentials* AsSecureCredentials() override { return this; } private: - std::shared_ptr CreateChannelWithInterceptors( + std::shared_ptr<::grpc::Channel> CreateChannelWithInterceptors( const grpc::string& target, const grpc::ChannelArguments& args, std::vector> + ::grpc::experimental::ClientInterceptorFactoryInterface>> interceptor_creators) override; grpc_channel_credentials* const c_creds_; }; From 657ab449c65e069b6523ac5624ac052a2c505b1c Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Fri, 26 Apr 2019 13:16:54 -0700 Subject: [PATCH 085/112] Make single-argument constructor explicit --- test/cpp/end2end/client_callback_end2end_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc index f0d159ba2a2..9acaf4d076b 100644 --- a/test/cpp/end2end/client_callback_end2end_test.cc +++ b/test/cpp/end2end/client_callback_end2end_test.cc @@ -536,9 +536,9 @@ TEST_P(ClientCallbackEnd2endTest, RequestEchoServerCancel) { struct ClientCancelInfo { bool cancel{false}; int ops_before_cancel; + ClientCancelInfo() : cancel{false} {} - // Allow the single-op version to be non-explicit for ease of use - ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {} + explicit ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {} }; class WriteClient : public grpc::experimental::ClientWriteReactor { @@ -651,7 +651,7 @@ TEST_P(ClientCallbackEnd2endTest, RequestStream) { TEST_P(ClientCallbackEnd2endTest, ClientCancelsRequestStream) { MAYBE_SKIP_TEST; ResetStub(); - WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, {2}}; + WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, ClientCancelInfo{2}}; test.Await(); // Make sure that the server interceptors got the cancel if (GetParam().use_interceptors) { @@ -869,7 +869,7 @@ TEST_P(ClientCallbackEnd2endTest, ResponseStream) { TEST_P(ClientCallbackEnd2endTest, ClientCancelsResponseStream) { MAYBE_SKIP_TEST; ResetStub(); - ReadClient test{stub_.get(), DO_NOT_CANCEL, 2}; + ReadClient test{stub_.get(), DO_NOT_CANCEL, ClientCancelInfo{2}}; test.Await(); // Because cancel in this case races with server finish, we can't be sure that // server interceptors even see cancellation @@ -1052,7 +1052,7 @@ TEST_P(ClientCallbackEnd2endTest, ClientCancelsBidiStream) { MAYBE_SKIP_TEST; ResetStub(); BidiClient test{stub_.get(), DO_NOT_CANCEL, - kServerDefaultResponseStreamsToSend, 2}; + kServerDefaultResponseStreamsToSend, ClientCancelInfo{2}}; test.Await(); // Make sure that the server interceptors were notified of a cancel if (GetParam().use_interceptors) { From 79c3990d50c2d8884fec2aa8c52de2a2db48e4aa Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 13:17:44 -0700 Subject: [PATCH 086/112] Move declaration order to how it was earlier in optional, and if check for uri --- src/core/ext/filters/client_channel/client_channel.cc | 7 ++++--- src/core/lib/gprpp/optional.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 85fd450ad49..248e7811bba 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1067,9 +1067,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error) return; } grpc_uri* uri = grpc_uri_parse(server_uri, true); - GPR_ASSERT(uri->path[0] != '\0'); - server_name_.reset( - gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + if (uri != nullptr && uri->path[0] != '\0') { + server_name_.reset( + gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path)); + } grpc_uri_destroy(uri); char* proxy_name = nullptr; grpc_channel_args* new_args = nullptr; diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index 87d336ad6d0..a8e3ce1505e 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -38,8 +38,8 @@ class Optional { T value() const { return value_; } private: - bool set_ = false; T value_; + bool set_ = false; }; } /* namespace grpc_core */ From 5ff8df71d48b7bb447dff2e98aa32a7f52640f12 Mon Sep 17 00:00:00 2001 From: Yash Tibrewal Date: Fri, 26 Apr 2019 13:41:30 -0700 Subject: [PATCH 087/112] Add default constructor back to optional --- .../ext/filters/client_channel/resolver_result_parsing.cc | 6 +++--- src/core/lib/gprpp/optional.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 35e54779c69..452dea6a0f7 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -416,8 +416,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json, "field:retryThrottling error:Type should be object")); continue; } - Optional max_milli_tokens = Optional(); - Optional milli_token_ratio = Optional(); + Optional max_milli_tokens; + Optional milli_token_ratio; for (grpc_json* sub_field = field->child; sub_field != nullptr; sub_field = sub_field->next) { if (sub_field->key == nullptr) continue; @@ -535,7 +535,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json, grpc_error** error) { GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); InlinedVector error_list; - Optional wait_for_ready = Optional(); + Optional wait_for_ready; grpc_millis timeout = 0; UniquePtr retry_policy; for (grpc_json* field = json->child; field != nullptr; field = field->next) { diff --git a/src/core/lib/gprpp/optional.h b/src/core/lib/gprpp/optional.h index a8e3ce1505e..ab5f86393b6 100644 --- a/src/core/lib/gprpp/optional.h +++ b/src/core/lib/gprpp/optional.h @@ -26,6 +26,7 @@ namespace grpc_core { template class Optional { public: + Optional() : value_() {} void set(const T& val) { value_ = val; set_ = true; From 9f3c78177f4e19d28027d06867493e09098ddaab Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 26 Apr 2019 15:40:53 -0700 Subject: [PATCH 088/112] Resolve final comments --- .../resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc | 6 +++--- .../resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc index c29fa44a353..e272e5a8800 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc @@ -77,7 +77,7 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { return false; } - void ShutdownInternal(grpc_error* error) { + void ShutdownInternalLocked(grpc_error* error) { uv_poll_stop(handle_); uv_close(reinterpret_cast(handle_), ares_uv_poll_close_cb); if (read_closure_ != nullptr) { @@ -91,9 +91,9 @@ class GrpcPolledFdLibuv : public GrpcPolledFd { void ShutdownLocked(grpc_error* error) override { if (grpc_core::ExecCtx::Get() == nullptr) { grpc_core::ExecCtx exec_ctx; - ShutdownInternal(error); + ShutdownInternalLocked(error); } else { - ShutdownInternal(error); + ShutdownInternalLocked(error); } } diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc index 706bc659582..07906f282aa 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv_windows.cc @@ -37,7 +37,7 @@ bool inner_maybe_resolve_localhost_manually_locked( gpr_split_host_port(name, host, port); if (*host == nullptr) { gpr_log(GPR_ERROR, - "Failed to parse %s into host:port during Windows localhost " + "Failed to parse %s into host:port during manual localhost " "resolution check.", name); return false; @@ -45,7 +45,7 @@ bool inner_maybe_resolve_localhost_manually_locked( if (*port == nullptr) { if (default_port == nullptr) { gpr_log(GPR_ERROR, - "No port or default port for %s during Windows localhost " + "No port or default port for %s during manual localhost " "resolution check.", name); return false; From b779a954b1f3b15ce4ec034e02f343c848012d31 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 19 Apr 2019 17:59:42 -0700 Subject: [PATCH 089/112] Inlined md_ref/unref and saved some unnecessary ops --- src/core/lib/transport/metadata.cc | 449 ++++++++++++----------------- src/core/lib/transport/metadata.h | 199 ++++++++++++- 2 files changed, 380 insertions(+), 268 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index b7e7fd40c00..03bd2056fbc 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -41,6 +41,10 @@ #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/transport/static_metadata.h" +using grpc_core::AllocatedMetadata; +using grpc_core::InternedMetadata; +using grpc_core::UserData; + /* There are two kinds of mdelem and mdstr instances. * Static instances are declared in static_metadata.{h,c} and * are initialized by grpc_mdctx_global_init(). @@ -54,13 +58,40 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #ifndef NDEBUG #define DEBUG_ARGS , const char *file, int line -#define FWD_DEBUG_ARGS , file, line -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s), __FILE__, __LINE__) -#else +#define FWD_DEBUG_ARGS file, line + +void grpc_mdelem_trace_ref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line) { + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md, refcnt, + refcnt + 1, key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +} + +void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line) { + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key); + char* value_str = grpc_slice_to_c_string(value); + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", md, + refcnt, refcnt - 1, key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +} + +#else // ifndef NDEBUG #define DEBUG_ARGS #define FWD_DEBUG_ARGS -#define REF_MD_LOCKED(shard, s) ref_md_locked((shard), (s)) -#endif +#endif // ifndef NDEBUG #define INITIAL_SHARD_CAPACITY 8 #define LOG2_SHARD_COUNT 4 @@ -69,43 +100,87 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_metadata(false, "metadata"); #define TABLE_IDX(hash, capacity) (((hash) >> (LOG2_SHARD_COUNT)) % (capacity)) #define SHARD_IDX(hash) ((hash) & ((1 << (LOG2_SHARD_COUNT)) - 1)) -typedef void (*destroy_user_data_func)(void* user_data); - -struct UserData { - gpr_mu mu_user_data; - gpr_atm destroy_user_data; - gpr_atm user_data; -}; - -/* Shadow structure for grpc_mdelem_data for interned elements */ -typedef struct interned_metadata { - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key; - grpc_slice value; - - /* private only data */ - gpr_atm refcnt; - - UserData user_data; +AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, + const grpc_slice& value) + : key_(grpc_slice_ref_internal(key)), + value_(grpc_slice_ref_internal(value)), + refcnt_(1) { +#ifndef NDEBUG + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", this, + RefValue(), key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +#endif +} - struct interned_metadata* bucket_next; -} interned_metadata; +AllocatedMetadata::~AllocatedMetadata() { + grpc_slice_unref_internal(key_); + grpc_slice_unref_internal(value_); + if (user_data_.user_data) { + destroy_user_data_func destroy_user_data = + (destroy_user_data_func)gpr_atm_no_barrier_load( + &user_data_.destroy_user_data); + destroy_user_data((void*)user_data_.user_data); + } +} -/* Shadow structure for grpc_mdelem_data for allocated elements */ -typedef struct allocated_metadata { - /* must be byte compatible with grpc_mdelem_data */ - grpc_slice key; - grpc_slice value; +InternedMetadata::InternedMetadata(const grpc_slice& key, + const grpc_slice& value, uint32_t hash, + InternedMetadata* next) + : key_(grpc_slice_ref_internal(key)), + value_(grpc_slice_ref_internal(value)), + refcnt_(1), + hash_(hash), + link_(next) { +#ifndef NDEBUG + if (grpc_trace_metadata.enabled()) { + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", this, + RefValue(), key_str, value_str); + gpr_free(key_str); + gpr_free(value_str); + } +#endif +} - /* private only data */ - gpr_atm refcnt; +InternedMetadata::~InternedMetadata() { + grpc_slice_unref_internal(key_); + grpc_slice_unref_internal(value_); + if (user_data_.user_data) { + destroy_user_data_func destroy_user_data = + (destroy_user_data_func)gpr_atm_no_barrier_load( + &user_data_.destroy_user_data); + destroy_user_data((void*)user_data_.user_data); + } +} - UserData user_data; -} allocated_metadata; +intptr_t InternedMetadata::CleanupLinkedMetadata( + InternedMetadata::BucketLink* head) { + intptr_t num_freed = 0; + InternedMetadata::BucketLink* prev_next = head; + InternedMetadata *md, *next; + + for (md = head->next; md; md = next) { + next = md->link_.next; + if (md->AllRefsDropped()) { + prev_next->next = next; + grpc_core::Delete(md); + num_freed++; + } else { + prev_next = &md->link_; + } + } + return num_freed; +} typedef struct mdtab_shard { gpr_mu mu; - interned_metadata** elems; + InternedMetadata::BucketLink* elems; size_t count; size_t capacity; /** Estimate of the number of unreferenced mdelems in the hash table. @@ -126,7 +201,7 @@ void grpc_mdctx_global_init(void) { shard->count = 0; gpr_atm_no_barrier_store(&shard->free_estimate, 0); shard->capacity = INITIAL_SHARD_CAPACITY; - shard->elems = static_cast( + shard->elems = static_cast( gpr_zalloc(sizeof(*shard->elems) * shard->capacity)); } } @@ -154,55 +229,29 @@ static int is_mdelem_static(grpc_mdelem e) { &grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; } -static void ref_md_locked(mdtab_shard* shard, - interned_metadata* md DEBUG_ARGS) { +void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { #ifndef NDEBUG if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", (void*)md, - gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); + char* key_str = grpc_slice_to_c_string(key_); + char* value_str = grpc_slice_to_c_string(value_); + intptr_t value = RefValue(); + gpr_log(__FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG, + "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", this, value, + value + 1, key_str, value_str); gpr_free(key_str); gpr_free(value_str); } #endif - if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) { + if (FirstRef()) { gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1); } } static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); - - size_t i; - interned_metadata** prev_next; - interned_metadata *md, *next; - gpr_atm num_freed = 0; - - for (i = 0; i < shard->capacity; i++) { - prev_next = &shard->elems[i]; - for (md = shard->elems[i]; md; md = next) { - void* user_data = - (void*)gpr_atm_no_barrier_load(&md->user_data.user_data); - next = md->bucket_next; - if (gpr_atm_acq_load(&md->refcnt) == 0) { - grpc_slice_unref_internal(md->key); - grpc_slice_unref_internal(md->value); - if (md->user_data.user_data) { - ((destroy_user_data_func)gpr_atm_no_barrier_load( - &md->user_data.destroy_user_data))(user_data); - } - gpr_mu_destroy(&md->user_data.mu_user_data); - gpr_free(md); - *prev_next = next; - num_freed++; - shard->count--; - } else { - prev_next = &md->bucket_next; - } - } + intptr_t num_freed = 0; + for (size_t i = 0; i < shard->capacity; ++i) { + num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); } gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed); } @@ -212,22 +261,21 @@ static void grow_mdtab(mdtab_shard* shard) { size_t capacity = shard->capacity * 2; size_t i; - interned_metadata** mdtab; - interned_metadata *md, *next; + InternedMetadata::BucketLink* mdtab; + InternedMetadata *md, *next; uint32_t hash; - mdtab = static_cast( - gpr_zalloc(sizeof(interned_metadata*) * capacity)); + mdtab = static_cast( + gpr_zalloc(sizeof(InternedMetadata::BucketLink) * capacity)); for (i = 0; i < shard->capacity; i++) { - for (md = shard->elems[i]; md; md = next) { + for (md = shard->elems[i].next; md; md = next) { size_t idx; - hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), - grpc_slice_hash(md->value)); - next = md->bucket_next; + hash = md->hash(); + next = md->bucket_next(); idx = TABLE_IDX(hash, capacity); - md->bucket_next = mdtab[idx]; - mdtab[idx] = md; + md->set_bucket_next(mdtab[idx].next); + mdtab[idx].next = md; } } gpr_free(shard->elems); @@ -247,34 +295,22 @@ static void rehash_mdtab(mdtab_shard* shard) { grpc_mdelem grpc_mdelem_create( const grpc_slice& key, const grpc_slice& value, grpc_mdelem_data* compatible_external_backing_store) { + // External storage if either slice is not interned and the caller already + // created a backing store. If no backing store, we allocate one. if (!grpc_slice_is_interned(key) || !grpc_slice_is_interned(value)) { if (compatible_external_backing_store != nullptr) { + // Caller provided backing store. return GRPC_MAKE_MDELEM(compatible_external_backing_store, GRPC_MDELEM_STORAGE_EXTERNAL); + } else { + // We allocate backing store. + return GRPC_MAKE_MDELEM(grpc_core::New(key, value), + GRPC_MDELEM_STORAGE_ALLOCATED); } - - allocated_metadata* allocated = - static_cast(gpr_malloc(sizeof(*allocated))); - allocated->key = grpc_slice_ref_internal(key); - allocated->value = grpc_slice_ref_internal(value); - gpr_atm_rel_store(&allocated->refcnt, 1); - allocated->user_data.user_data = 0; - allocated->user_data.destroy_user_data = 0; - gpr_mu_init(&allocated->user_data.mu_user_data); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(allocated->key); - char* value_str = grpc_slice_to_c_string(allocated->value); - gpr_log(GPR_DEBUG, "ELM ALLOC:%p:%" PRIdPTR ": '%s' = '%s'", - (void*)allocated, gpr_atm_no_barrier_load(&allocated->refcnt), - key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - return GRPC_MAKE_MDELEM(allocated, GRPC_MDELEM_STORAGE_ALLOCATED); } + // Not all static slice input yields a statically stored metadata element. + // It may be worth documenting why. if (GRPC_IS_STATIC_METADATA_STRING(key) && GRPC_IS_STATIC_METADATA_STRING(value)) { grpc_mdelem static_elem = grpc_static_mdelem_for_static_strings( @@ -286,7 +322,7 @@ grpc_mdelem grpc_mdelem_create( uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(key), grpc_slice_hash(value)); - interned_metadata* md; + InternedMetadata* md; mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; size_t idx; @@ -296,34 +332,18 @@ grpc_mdelem grpc_mdelem_create( idx = TABLE_IDX(hash, shard->capacity); /* search for an existing pair */ - for (md = shard->elems[idx]; md; md = md->bucket_next) { - if (grpc_slice_eq(key, md->key) && grpc_slice_eq(value, md->value)) { - REF_MD_LOCKED(shard, md); + for (md = shard->elems[idx].next; md; md = md->bucket_next()) { + if (grpc_slice_eq(key, md->key()) && grpc_slice_eq(value, md->value())) { + md->RefWithShardLocked(shard); gpr_mu_unlock(&shard->mu); return GRPC_MAKE_MDELEM(md, GRPC_MDELEM_STORAGE_INTERNED); } } /* not found: create a new pair */ - md = static_cast(gpr_malloc(sizeof(interned_metadata))); - gpr_atm_rel_store(&md->refcnt, 1); - md->key = grpc_slice_ref_internal(key); - md->value = grpc_slice_ref_internal(value); - md->user_data.user_data = 0; - md->user_data.destroy_user_data = 0; - md->bucket_next = shard->elems[idx]; - shard->elems[idx] = md; - gpr_mu_init(&md->user_data.mu_user_data); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(GPR_DEBUG, "ELM NEW:%p:%" PRIdPTR ": '%s' = '%s'", (void*)md, - gpr_atm_no_barrier_load(&md->refcnt), key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif + md = grpc_core::New(key, value, hash, + shard->elems[idx].next); + shard->elems[idx].next = md; shard->count++; if (shard->count > shard->capacity * 2) { @@ -354,126 +374,6 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { changed ? nullptr : reinterpret_cast(metadata)); } -grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd DEBUG_ARGS) { - switch (GRPC_MDELEM_STORAGE(gmd)) { - case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_STATIC: - break; - case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1); - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - break; - } - case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM REF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) + 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - /* we can assume the ref count is >= 1 as the application is calling - this function - meaning that no adjustment to mdtab_free is necessary, - simplifying the logic here to be just an atomic increment */ - /* use C assert to have this removed in opt builds */ - gpr_atm_no_barrier_fetch_add(&md->refcnt, 1); - break; - } - } - return gmd; -} - -void grpc_mdelem_unref(grpc_mdelem gmd DEBUG_ARGS) { - switch (GRPC_MDELEM_STORAGE(gmd)) { - case GRPC_MDELEM_STORAGE_EXTERNAL: - case GRPC_MDELEM_STORAGE_STATIC: - break; - case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - uint32_t hash = GRPC_MDSTR_KV_HASH(grpc_slice_hash(md->key), - grpc_slice_hash(md->value)); - const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); - GPR_ASSERT(prev_refcount >= 1); - if (1 == prev_refcount) { - /* once the refcount hits zero, some other thread can come along and - free md at any time: it's unsafe from this point on to access it */ - mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; - gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); - } - break; - } - case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* md = - reinterpret_cast GRPC_MDELEM_DATA(gmd); -#ifndef NDEBUG - if (grpc_trace_metadata.enabled()) { - char* key_str = grpc_slice_to_c_string(md->key); - char* value_str = grpc_slice_to_c_string(md->value); - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "ELM UNREF:%p:%" PRIdPTR "->%" PRIdPTR ": '%s' = '%s'", - (void*)md, gpr_atm_no_barrier_load(&md->refcnt), - gpr_atm_no_barrier_load(&md->refcnt) - 1, key_str, value_str); - gpr_free(key_str); - gpr_free(value_str); - } -#endif - const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1); - GPR_ASSERT(prev_refcount >= 1); - if (1 == prev_refcount) { - grpc_slice_unref_internal(md->key); - grpc_slice_unref_internal(md->value); - if (md->user_data.user_data) { - destroy_user_data_func destroy_user_data = - (destroy_user_data_func)gpr_atm_no_barrier_load( - &md->user_data.destroy_user_data); - destroy_user_data((void*)md->user_data.user_data); - } - gpr_mu_destroy(&md->user_data.mu_user_data); - gpr_free(md); - } - break; - } - } -} - static void* get_user_data(UserData* user_data, void (*destroy_func)(void*)) { if (gpr_atm_acq_load(&user_data->destroy_user_data) == (gpr_atm)destroy_func) { @@ -491,14 +391,12 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* am = - reinterpret_cast(GRPC_MDELEM_DATA(md)); - return get_user_data(&am->user_data, destroy_func); + auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); + return get_user_data(am->user_data(), destroy_func); } case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* im = - reinterpret_cast GRPC_MDELEM_DATA(md); - return get_user_data(&im->user_data, destroy_func); + auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); + return get_user_data(im->user_data(), destroy_func); } } GPR_UNREACHABLE_CODE(return nullptr); @@ -507,10 +405,10 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { static void* set_user_data(UserData* ud, void (*destroy_func)(void*), void* user_data) { GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); - gpr_mu_lock(&ud->mu_user_data); + grpc_core::ReleasableMutexLock lock(&ud->mu_user_data); if (gpr_atm_no_barrier_load(&ud->destroy_user_data)) { /* user data can only be set once */ - gpr_mu_unlock(&ud->mu_user_data); + lock.Unlock(); if (destroy_func != nullptr) { destroy_func(user_data); } @@ -518,7 +416,6 @@ static void* set_user_data(UserData* ud, void (*destroy_func)(void*), } gpr_atm_no_barrier_store(&ud->user_data, (gpr_atm)user_data); gpr_atm_rel_store(&ud->destroy_user_data, (gpr_atm)destroy_func); - gpr_mu_unlock(&ud->mu_user_data); return user_data; } @@ -533,15 +430,13 @@ void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; case GRPC_MDELEM_STORAGE_ALLOCATED: { - allocated_metadata* am = - reinterpret_cast(GRPC_MDELEM_DATA(md)); - return set_user_data(&am->user_data, destroy_func, user_data); + auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); + return set_user_data(am->user_data(), destroy_func, user_data); } case GRPC_MDELEM_STORAGE_INTERNED: { - interned_metadata* im = - reinterpret_cast GRPC_MDELEM_DATA(md); + auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); GPR_ASSERT(!is_mdelem_static(md)); - return set_user_data(&im->user_data, destroy_func, user_data); + return set_user_data(im->user_data(), destroy_func, user_data); } } GPR_UNREACHABLE_CODE(return nullptr); @@ -554,3 +449,33 @@ bool grpc_mdelem_eq(grpc_mdelem a, grpc_mdelem b) { return grpc_slice_eq(GRPC_MDKEY(a), GRPC_MDKEY(b)) && grpc_slice_eq(GRPC_MDVALUE(a), GRPC_MDVALUE(b)); } + +static void note_disposed_interned_metadata(uint32_t hash) { + mdtab_shard* shard = &g_shards[SHARD_IDX(hash)]; + gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1); +} + +void grpc_mdelem_do_unref(grpc_mdelem gmd DEBUG_ARGS) { + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: { + auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); + uint32_t hash = md->hash(); + if (md->Unref(FWD_DEBUG_ARGS)) { + /* once the refcount hits zero, some other thread can come along and + free md at any time: it's unsafe from this point on to access it */ + note_disposed_interned_metadata(hash); + } + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* md = reinterpret_cast GRPC_MDELEM_DATA(gmd); + if (md->Unref(FWD_DEBUG_ARGS)) { + grpc_core::Delete(md); + } + break; + } + } +} diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 5e016567eb2..d431474d017 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -21,11 +21,15 @@ #include +#include "include/grpc/impl/codegen/log.h" + #include #include #include "src/core/lib/debug/trace.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/sync.h" extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; @@ -63,7 +67,7 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_metadata; typedef struct grpc_mdelem grpc_mdelem; /* if changing this, make identical changes in: - - interned_metadata, allocated_metadata in metadata.c + - grpc_core::{InternedMetadata, AllocatedMetadata} - grpc_metadata in grpc_types.h */ typedef struct grpc_mdelem_data { const grpc_slice key; @@ -143,17 +147,200 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), void* user_data); +// Defined in metadata.cc. +struct mdtab_shard; + +#ifndef NDEBUG +void grpc_mdelem_trace_ref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line); +void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, + const grpc_slice& value, intptr_t refcnt, + const char* file, int line); +#endif +namespace grpc_core { + +typedef void (*destroy_user_data_func)(void* user_data); + +struct UserData { + Mutex mu_user_data; + gpr_atm destroy_user_data = 0; + gpr_atm user_data = 0; +}; + +class InternedMetadata { + public: + struct BucketLink { + explicit BucketLink(InternedMetadata* md) : next(md) {} + + InternedMetadata* next = nullptr; + }; + + InternedMetadata(const grpc_slice& key, const grpc_slice& value, + uint32_t hash, InternedMetadata* next); + ~InternedMetadata(); + +#ifndef NDEBUG + void Ref(const char* file, int line) { + grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); + const intptr_t prior = refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + GPR_ASSERT(prior > 0); + } + bool Unref(const char* file, int line) { + grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); + return Unref(); + } +#else + // We define a naked Ref() in the else-clause to make sure we don't + // inadvertently skip the assert on debug builds. + void Ref() { + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + } +#endif // ifndef NDEBUG + bool Unref() { + const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + void RefWithShardLocked(mdtab_shard* shard); + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + UserData* user_data() { return &user_data_; } + uint32_t hash() { return hash_; } + InternedMetadata* bucket_next() { return link_.next; } + void set_bucket_next(InternedMetadata* md) { link_.next = md; } + + static intptr_t CleanupLinkedMetadata(BucketLink* head); + + private: + bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; } + bool FirstRef() { return refcnt_.FetchAdd(1, MemoryOrder::RELAXED) == 0; } + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + + /* must be byte compatible with grpc_mdelem_data */ + grpc_slice key_; + grpc_slice value_; + + /* private only data */ + grpc_core::Atomic refcnt_; + uint32_t hash_; + + UserData user_data_; + + BucketLink link_; +}; + +/* Shadow structure for grpc_mdelem_data for allocated elements */ +class AllocatedMetadata { + public: + AllocatedMetadata(const grpc_slice& key, const grpc_slice& value); + ~AllocatedMetadata(); + + const grpc_slice& key() const { return key_; } + const grpc_slice& value() const { return value_; } + UserData* user_data() { return &user_data_; } + +#ifndef NDEBUG + void Ref(const char* file, int line) { + grpc_mdelem_trace_ref(this, key_, value_, RefValue(), file, line); + Ref(); + } + bool Unref(const char* file, int line) { + grpc_mdelem_trace_unref(this, key_, value_, RefValue(), file, line); + return Unref(); + } +#endif // ifndef NDEBUG + void Ref() { + /* we can assume the ref count is >= 1 as the application is calling + this function - meaning that no adjustment to mdtab_free is necessary, + simplifying the logic here to be just an atomic increment */ + refcnt_.FetchAdd(1, MemoryOrder::RELAXED); + } + bool Unref() { + const intptr_t prior = refcnt_.FetchSub(1, MemoryOrder::ACQ_REL); + GPR_DEBUG_ASSERT(prior > 0); + return prior == 1; + } + + private: + intptr_t RefValue() { return refcnt_.Load(MemoryOrder::RELAXED); } + + /* must be byte compatible with grpc_mdelem_data */ + grpc_slice key_; + grpc_slice value_; + + /* private only data */ + grpc_core::Atomic refcnt_; + + UserData user_data_; +}; + +} // namespace grpc_core + #ifndef NDEBUG #define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s), __FILE__, __LINE__) +inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd, const char* file, + int line) { +#else // ifndef NDEBUG +#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) +inline grpc_mdelem grpc_mdelem_ref(grpc_mdelem gmd) { +#endif // ifndef NDEBUG + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + break; + case GRPC_MDELEM_STORAGE_INTERNED: { + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); + /* use C assert to have this removed in opt builds */ +#ifndef NDEBUG + md->Ref(file, line); +#else + md->Ref(); +#endif + break; + } + case GRPC_MDELEM_STORAGE_ALLOCATED: { + auto* md = + reinterpret_cast GRPC_MDELEM_DATA(gmd); +#ifndef NDEBUG + md->Ref(file, line); +#else + md->Ref(); +#endif + break; + } + } + return gmd; +} + +#ifndef NDEBUG #define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s), __FILE__, __LINE__) -grpc_mdelem grpc_mdelem_ref(grpc_mdelem md, const char* file, int line); -void grpc_mdelem_unref(grpc_mdelem md, const char* file, int line); +void grpc_mdelem_do_unref(grpc_mdelem gmd, const char* file, int line); +inline void grpc_mdelem_unref(grpc_mdelem gmd, const char* file, int line) { #else -#define GRPC_MDELEM_REF(s) grpc_mdelem_ref((s)) #define GRPC_MDELEM_UNREF(s) grpc_mdelem_unref((s)) -grpc_mdelem grpc_mdelem_ref(grpc_mdelem md); -void grpc_mdelem_unref(grpc_mdelem md); +void grpc_mdelem_do_unref(grpc_mdelem gmd); +inline void grpc_mdelem_unref(grpc_mdelem gmd) { #endif + switch (GRPC_MDELEM_STORAGE(gmd)) { + case GRPC_MDELEM_STORAGE_EXTERNAL: + case GRPC_MDELEM_STORAGE_STATIC: + return; + case GRPC_MDELEM_STORAGE_INTERNED: + case GRPC_MDELEM_STORAGE_ALLOCATED: +#ifndef NDEBUG + grpc_mdelem_do_unref(gmd, file, line); +#else + grpc_mdelem_do_unref(gmd); +#endif + return; + } +} #define GRPC_MDNULL GRPC_MAKE_MDELEM(NULL, GRPC_MDELEM_STORAGE_EXTERNAL) #define GRPC_MDISNULL(md) (GRPC_MDELEM_DATA(md) == NULL) From f371d95c479d4e184abd435ff9d7fbbba6de011a Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Fri, 26 Apr 2019 17:03:16 -0700 Subject: [PATCH 090/112] Handle protos at root package level --- bazel/generate_cc.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 83a0927da89..82f5cbad310 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -19,6 +19,8 @@ _PROTO_HEADER_FMT = "{}.pb.h" _PROTO_SRC_FMT = "{}.pb.cc" def _strip_package_from_path(label_package, path): + if len(label_package) == 0: + return path if not path.startswith(label_package + "/"): fail("'{}' does not lie within '{}'.".format(path, label_package)) return path[len(label_package + "/"):] From 664d4d984b819eeb90807d80378d92c41ce8a9ac Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 26 Apr 2019 16:07:15 -0700 Subject: [PATCH 091/112] Removed gpr_atm from UserData --- src/core/lib/transport/metadata.cc | 57 +++++++++++++++--------------- src/core/lib/transport/metadata.h | 10 +++--- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index 03bd2056fbc..e3b8d112795 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -120,11 +120,11 @@ AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, AllocatedMetadata::~AllocatedMetadata() { grpc_slice_unref_internal(key_); grpc_slice_unref_internal(value_); - if (user_data_.user_data) { + void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); + if (user_data) { destroy_user_data_func destroy_user_data = - (destroy_user_data_func)gpr_atm_no_barrier_load( - &user_data_.destroy_user_data); - destroy_user_data((void*)user_data_.user_data); + user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); + destroy_user_data(user_data); } } @@ -151,17 +151,17 @@ InternedMetadata::InternedMetadata(const grpc_slice& key, InternedMetadata::~InternedMetadata() { grpc_slice_unref_internal(key_); grpc_slice_unref_internal(value_); - if (user_data_.user_data) { + void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); + if (user_data) { destroy_user_data_func destroy_user_data = - (destroy_user_data_func)gpr_atm_no_barrier_load( - &user_data_.destroy_user_data); - destroy_user_data((void*)user_data_.user_data); + user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); + destroy_user_data(user_data); } } -intptr_t InternedMetadata::CleanupLinkedMetadata( +size_t InternedMetadata::CleanupLinkedMetadata( InternedMetadata::BucketLink* head) { - intptr_t num_freed = 0; + size_t num_freed = 0; InternedMetadata::BucketLink* prev_next = head; InternedMetadata *md, *next; @@ -249,11 +249,12 @@ void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); - intptr_t num_freed = 0; + size_t num_freed = 0; for (size_t i = 0; i < shard->capacity; ++i) { num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); } - gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed); + gpr_atm_no_barrier_fetch_add(&shard->free_estimate, + -static_cast(num_freed)); } static void grow_mdtab(mdtab_shard* shard) { @@ -375,9 +376,9 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { } static void* get_user_data(UserData* user_data, void (*destroy_func)(void*)) { - if (gpr_atm_acq_load(&user_data->destroy_user_data) == - (gpr_atm)destroy_func) { - return (void*)gpr_atm_no_barrier_load(&user_data->user_data); + if (user_data->destroy_user_data.Load(grpc_core::MemoryOrder::ACQUIRE) == + destroy_func) { + return user_data->data.Load(grpc_core::MemoryOrder::RELAXED); } else { return nullptr; } @@ -403,40 +404,40 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { } static void* set_user_data(UserData* ud, void (*destroy_func)(void*), - void* user_data) { - GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); + void* data) { + GPR_ASSERT((data == nullptr) == (destroy_func == nullptr)); grpc_core::ReleasableMutexLock lock(&ud->mu_user_data); - if (gpr_atm_no_barrier_load(&ud->destroy_user_data)) { + if (ud->destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED)) { /* user data can only be set once */ lock.Unlock(); if (destroy_func != nullptr) { - destroy_func(user_data); + destroy_func(data); } - return (void*)gpr_atm_no_barrier_load(&ud->user_data); + return ud->data.Load(grpc_core::MemoryOrder::RELAXED); } - gpr_atm_no_barrier_store(&ud->user_data, (gpr_atm)user_data); - gpr_atm_rel_store(&ud->destroy_user_data, (gpr_atm)destroy_func); - return user_data; + ud->data.Store(data, grpc_core::MemoryOrder::RELAXED); + ud->destroy_user_data.Store(destroy_func, grpc_core::MemoryOrder::RELEASE); + return data; } void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), - void* user_data) { + void* data) { switch (GRPC_MDELEM_STORAGE(md)) { case GRPC_MDELEM_STORAGE_EXTERNAL: - destroy_func(user_data); + destroy_func(data); return nullptr; case GRPC_MDELEM_STORAGE_STATIC: - destroy_func(user_data); + destroy_func(data); return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - grpc_static_mdelem_table]; case GRPC_MDELEM_STORAGE_ALLOCATED: { auto* am = reinterpret_cast(GRPC_MDELEM_DATA(md)); - return set_user_data(am->user_data(), destroy_func, user_data); + return set_user_data(am->user_data(), destroy_func, data); } case GRPC_MDELEM_STORAGE_INTERNED: { auto* im = reinterpret_cast GRPC_MDELEM_DATA(md); GPR_ASSERT(!is_mdelem_static(md)); - return set_user_data(im->user_data(), destroy_func, user_data); + return set_user_data(im->user_data(), destroy_func, data); } } GPR_UNREACHABLE_CODE(return nullptr); diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index d431474d017..c0d1ab36351 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -145,7 +145,7 @@ inline bool grpc_mdelem_static_value_eq(grpc_mdelem a, grpc_mdelem b_static) { is used as a type tag and is checked during user_data fetch. */ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*if_destroy_func)(void*)); void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), - void* user_data); + void* data); // Defined in metadata.cc. struct mdtab_shard; @@ -160,12 +160,12 @@ void grpc_mdelem_trace_unref(void* md, const grpc_slice& key, #endif namespace grpc_core { -typedef void (*destroy_user_data_func)(void* user_data); +typedef void (*destroy_user_data_func)(void* data); struct UserData { Mutex mu_user_data; - gpr_atm destroy_user_data = 0; - gpr_atm user_data = 0; + grpc_core::Atomic destroy_user_data; + grpc_core::Atomic data; }; class InternedMetadata { @@ -214,7 +214,7 @@ class InternedMetadata { InternedMetadata* bucket_next() { return link_.next; } void set_bucket_next(InternedMetadata* md) { link_.next = md; } - static intptr_t CleanupLinkedMetadata(BucketLink* head); + static size_t CleanupLinkedMetadata(BucketLink* head); private: bool AllRefsDropped() { return refcnt_.Load(MemoryOrder::ACQUIRE) == 0; } From 069547e944bad1c2c1a0fb232ebf6159fc359ca8 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Sun, 28 Apr 2019 17:14:05 -0400 Subject: [PATCH 092/112] Fix a typo in chttp2 stream initialization. Found this during performance optimizations. We always reinitialize this to the correct value, so this wasn't caught in tests. --- src/core/ext/transport/chttp2/transport/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index 2e2b3251b4f..00b1fe18b28 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -633,7 +633,7 @@ struct grpc_chttp2_stream { GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; /* Stream decompression method to be used. */ grpc_stream_compression_method stream_decompression_method = - GRPC_STREAM_COMPRESSION_IDENTITY_COMPRESS; + GRPC_STREAM_COMPRESSION_IDENTITY_DECOMPRESS; /** Stream compression decompress context */ grpc_stream_compression_context* stream_decompression_ctx = nullptr; /** Stream compression compress context */ From 952ddb6a2bceed3f21aa1ef18e42aa24b7fa538d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 29 Apr 2019 12:06:34 -0400 Subject: [PATCH 093/112] fix uploading bazel RBE results to bigquery --- tools/run_tests/python_utils/upload_rbe_results.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index bda567e977e..e6504799d66 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -146,6 +146,8 @@ if __name__ == "__main__": invocation_id = args.invocation_id or _get_invocation_id() resultstore_actions = _get_resultstore_data(api_key, invocation_id) + # google.devtools.resultstore.v2.Action schema: + # https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/action.proto bq_rows = [] for index, action in enumerate(resultstore_actions): # Filter out non-test related data, such as build results. @@ -187,6 +189,8 @@ if __name__ == "__main__": } elif 'testSuite' not in action['testAction']: continue + elif 'tests' not in action['testAction']['testSuite']: + continue else: test_cases = action['testAction']['testSuite']['tests'][0][ 'testSuite']['tests'] From ed432363775377da49b179cd66131a6f6dcd1877 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Fri, 26 Apr 2019 18:58:47 -0700 Subject: [PATCH 094/112] Coalesce arena create/first alloc for grpc_call. --- src/core/lib/gprpp/arena.cc | 37 ++++++++++++++++++++++++------------ src/core/lib/gprpp/arena.h | 24 ++++++++++++++++++++++- src/core/lib/surface/call.cc | 20 +++++++++++++------ 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc index ab3a4865a12..5c344db4e35 100644 --- a/src/core/lib/gprpp/arena.cc +++ b/src/core/lib/gprpp/arena.cc @@ -31,11 +31,23 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/memory.h" -template -static void* gpr_arena_malloc(size_t size) { - return gpr_malloc_aligned(size, alignment); +namespace { + +void* ArenaStorage(size_t initial_size) { + static constexpr size_t base_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); + initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); + size_t alloc_size = base_size + initial_size; + static constexpr size_t alignment = + (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && + GPR_CACHELINE_SIZE % GPR_MAX_ALIGNMENT == 0) + ? GPR_CACHELINE_SIZE + : GPR_MAX_ALIGNMENT; + return gpr_malloc_aligned(alloc_size, alignment); } +} // namespace + namespace grpc_core { Arena::~Arena() { @@ -49,16 +61,17 @@ Arena::~Arena() { } Arena* Arena::Create(size_t initial_size) { + return new (ArenaStorage(initial_size)) Arena(initial_size); +} + +Pair Arena::CreateWithAlloc(size_t initial_size, + size_t alloc_size) { static constexpr size_t base_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); - initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); - size_t alloc_size = base_size + initial_size; - static constexpr size_t alignment = - (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && - GPR_CACHELINE_SIZE % GPR_MAX_ALIGNMENT == 0) - ? GPR_CACHELINE_SIZE - : GPR_MAX_ALIGNMENT; - return new (gpr_arena_malloc(alloc_size)) Arena(initial_size); + auto* new_arena = + new (ArenaStorage(initial_size)) Arena(initial_size, alloc_size); + void* first_alloc = reinterpret_cast(new_arena) + base_size; + return MakePair(new_arena, first_alloc); } size_t Arena::Destroy() { @@ -77,7 +90,7 @@ void* Arena::AllocZone(size_t size) { static constexpr size_t zone_base_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Zone)); size_t alloc_size = zone_base_size + size; - Zone* z = new (gpr_arena_malloc(alloc_size)) Zone(); + Zone* z = new (gpr_malloc_aligned(alloc_size, GPR_MAX_ALIGNMENT)) Zone(); { gpr_spinlock_lock(&arena_growth_spinlock_); z->prev = last_zone_; diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h index 749f4e47ee8..b1b0c4a85cb 100644 --- a/src/core/lib/gprpp/arena.h +++ b/src/core/lib/gprpp/arena.h @@ -36,6 +36,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gpr/spinlock.h" #include "src/core/lib/gprpp/atomic.h" +#include "src/core/lib/gprpp/pair.h" #include @@ -45,6 +46,13 @@ class Arena { public: // Create an arena, with \a initial_size bytes in the first allocated buffer. static Arena* Create(size_t initial_size); + + // Create an arena, with \a initial_size bytes in the first allocated buffer, + // and return both a void pointer to the returned arena and a void* with the + // first allocation. + static Pair CreateWithAlloc(size_t initial_size, + size_t alloc_size); + // Destroy an arena, returning the total number of bytes allocated. size_t Destroy(); // Allocate \a size bytes from the arena. @@ -76,7 +84,21 @@ class Arena { Zone* prev; }; - explicit Arena(size_t initial_size) : initial_zone_size_(initial_size) {} + // Initialize an arena. + // Parameters: + // initial_size: The initial size of the whole arena in bytes. These bytes + // are contained within 'zone 0'. If the arena user ends up requiring more + // memory than the arena contains in zone 0, subsequent zones are allocated + // on demand and maintained in a tail-linked list. + // + // initial_alloc: Optionally, construct the arena as though a call to + // Alloc() had already been made for initial_alloc bytes. This provides a + // quick optimization (avoiding an atomic fetch-add) for the common case + // where we wish to create an arena and then perform an immediate + // allocation. + explicit Arena(size_t initial_size, size_t initial_alloc = 0) + : total_used_(initial_alloc), initial_zone_size_(initial_size) {} + ~Arena(); void* AllocZone(size_t size); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 54fdacd847c..bd140021c96 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -321,16 +321,23 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, GRPC_CHANNEL_INTERNAL_REF(args->channel, "call"); + grpc_core::Arena* arena; + grpc_call* call; grpc_error* error = GRPC_ERROR_NONE; grpc_channel_stack* channel_stack = grpc_channel_get_channel_stack(args->channel); - grpc_call* call; size_t initial_size = grpc_channel_get_call_size_estimate(args->channel); GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size); - grpc_core::Arena* arena = grpc_core::Arena::Create(initial_size); - call = new (arena->Alloc(GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + - channel_stack->call_stack_size)) - grpc_call(arena, *args); + size_t call_and_stack_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + + channel_stack->call_stack_size; + size_t call_alloc_size = + call_and_stack_size + (args->parent ? sizeof(child_call) : 0); + + std::pair arena_with_call = + grpc_core::Arena::CreateWithAlloc(initial_size, call_alloc_size); + arena = arena_with_call.first; + call = new (arena_with_call.second) grpc_call(arena, *args); *out_call = call; grpc_slice path = grpc_empty_slice(); if (call->is_client) { @@ -362,7 +369,8 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, bool immediately_cancel = false; if (args->parent != nullptr) { - call->child = arena->New(args->parent); + call->child = new (reinterpret_cast(arena_with_call.second) + + call_and_stack_size) child_call(args->parent); GRPC_CALL_INTERNAL_REF(args->parent, "child"); GPR_ASSERT(call->is_client); From 5e7e4946384d74e05fb140fa0a904e5427cb1f95 Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 29 Apr 2019 12:26:50 -0700 Subject: [PATCH 095/112] Use milliseconds for test_server timeout --- test/core/end2end/bad_server_response_test.cc | 2 +- test/core/util/reconnect_server.cc | 2 +- test/core/util/test_tcp_server.cc | 6 +++--- test/core/util/test_tcp_server.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index 3701a938a3d..2d74b6b77b3 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -250,7 +250,7 @@ static void actually_poll_server(void* arg) { if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) { break; } - test_tcp_server_poll(pa->server, 1); + test_tcp_server_poll(pa->server, 1000); } gpr_event_set(pa->signal_when_done, (void*)1); gpr_free(pa); diff --git a/test/core/util/reconnect_server.cc b/test/core/util/reconnect_server.cc index ad7cf42f71f..144ad64f095 100644 --- a/test/core/util/reconnect_server.cc +++ b/test/core/util/reconnect_server.cc @@ -109,7 +109,7 @@ void reconnect_server_start(reconnect_server* server, int port) { } void reconnect_server_poll(reconnect_server* server, int seconds) { - test_tcp_server_poll(&server->tcp_server, seconds); + test_tcp_server_poll(&server->tcp_server, 1000 * seconds); } void reconnect_server_clear_timestamps(reconnect_server* server) { diff --git a/test/core/util/test_tcp_server.cc b/test/core/util/test_tcp_server.cc index 610a9918ce6..80d0634a9b9 100644 --- a/test/core/util/test_tcp_server.cc +++ b/test/core/util/test_tcp_server.cc @@ -77,11 +77,11 @@ void test_tcp_server_start(test_tcp_server* server, int port) { gpr_log(GPR_INFO, "test tcp server listening on 0.0.0.0:%d", port); } -void test_tcp_server_poll(test_tcp_server* server, int seconds) { +void test_tcp_server_poll(test_tcp_server* server, int milliseconds) { grpc_pollset_worker* worker = nullptr; grpc_core::ExecCtx exec_ctx; grpc_millis deadline = grpc_timespec_to_millis_round_up( - grpc_timeout_seconds_to_deadline(seconds)); + grpc_timeout_milliseconds_to_deadline(milliseconds)); gpr_mu_lock(server->mu); GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(server->pollset, &worker, deadline)); @@ -104,7 +104,7 @@ void test_tcp_server_destroy(test_tcp_server* server) { gpr_time_from_seconds(5, GPR_TIMESPAN)); while (!server->shutdown && gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), shutdown_deadline) < 0) { - test_tcp_server_poll(server, 1); + test_tcp_server_poll(server, 1000); } grpc_pollset_shutdown(server->pollset, GRPC_CLOSURE_CREATE(finish_pollset, server->pollset, diff --git a/test/core/util/test_tcp_server.h b/test/core/util/test_tcp_server.h index 58140388da3..313a27a3334 100644 --- a/test/core/util/test_tcp_server.h +++ b/test/core/util/test_tcp_server.h @@ -35,7 +35,7 @@ typedef struct test_tcp_server { void test_tcp_server_init(test_tcp_server* server, grpc_tcp_server_cb on_connect, void* user_data); void test_tcp_server_start(test_tcp_server* server, int port); -void test_tcp_server_poll(test_tcp_server* server, int seconds); +void test_tcp_server_poll(test_tcp_server* server, int milliseconds); void test_tcp_server_destroy(test_tcp_server* server); #endif /* GRPC_TEST_CORE_UTIL_TEST_TCP_SERVER_H */ From 333ba8feaea465e35678c356542915140605b444 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Thu, 25 Apr 2019 17:31:20 -0700 Subject: [PATCH 096/112] Use aligned_alloc directly for grpc_core::Arena --- include/grpc/impl/codegen/port_platform.h | 3 + include/grpc/support/alloc.h | 2 + src/core/lib/gpr/alloc.cc | 78 ++++++++++++++++++++--- src/core/lib/gpr/alloc.h | 8 +++ src/core/lib/gprpp/arena.h | 2 +- test/core/gpr/alloc_test.cc | 18 +++++- test/core/util/memory_counters.cc | 8 ++- 7 files changed, 105 insertions(+), 14 deletions(-) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index d7294d59d41..ff759d2baed 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -77,6 +77,7 @@ #define GPR_WINDOWS 1 #define GPR_WINDOWS_SUBPROCESS 1 #define GPR_WINDOWS_ENV +#define GPR_HAS_ALIGNED_MALLOC 1 #ifdef __MSYS__ #define GPR_GETPID_IN_UNISTD_H 1 #define GPR_MSYS_TMPFILE @@ -173,6 +174,7 @@ #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 #define GPR_HAS_PTHREAD_H 1 +#define GPR_HAS_ALIGNED_ALLOC 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifdef _LP64 #define GPR_ARCH_64 1 @@ -238,6 +240,7 @@ #define GPR_POSIX_SUBPROCESS 1 #define GPR_POSIX_SYNC 1 #define GPR_POSIX_TIME 1 +#define GPR_HAS_POSIX_MEMALIGN 1 #define GPR_HAS_PTHREAD_H 1 #define GPR_GETPID_IN_UNISTD_H 1 #ifndef GRPC_CFSTREAM diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h index 8bd940bec47..4d8e007a577 100644 --- a/include/grpc/support/alloc.h +++ b/include/grpc/support/alloc.h @@ -32,6 +32,8 @@ typedef struct gpr_allocation_functions { void* (*zalloc_fn)(size_t size); /** if NULL, uses malloc_fn then memset */ void* (*realloc_fn)(void* ptr, size_t size); void (*free_fn)(void* ptr); + void* (*aligned_alloc_fn)(size_t size, size_t alignment); + void (*aligned_free_fn)(void* ptr); } gpr_allocation_functions; /** malloc. diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index 611e4cceee4..b601ad79f79 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -23,6 +23,7 @@ #include #include #include +#include "src/core/lib/gpr/alloc.h" #include "src/core/lib/profiling/timers.h" static void* zalloc_with_calloc(size_t sz) { return calloc(sz, 1); } @@ -33,8 +34,61 @@ static void* zalloc_with_gpr_malloc(size_t sz) { return p; } -static gpr_allocation_functions g_alloc_functions = {malloc, zalloc_with_calloc, - realloc, free}; +static constexpr bool is_power_of_two(size_t value) { + // 2^N = 100000...000 + // 2^N - 1 = 011111...111 + // (2^N) && ((2^N)-1)) = 0 + return (value & (value - 1)) == 0; +} + +static void* aligned_alloc_with_gpr_malloc(size_t size, size_t alignment) { + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + size_t extra = alignment - 1 + sizeof(void*); + void* p = gpr_malloc(size + extra); + void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); + ret[-1] = p; + return (void*)ret; +} + +static void aligned_free_with_gpr_malloc(void* ptr) { + gpr_free((static_cast(ptr))[-1]); +} + +static void* platform_malloc_aligned(size_t size, size_t alignment) { +#if defined(GPR_HAS_ALIGNED_ALLOC) + size = GPR_ROUND_UP_TO_SPECIFIED_SIZE(size, alignment); + void* ret = aligned_alloc(alignment, size); + GPR_ASSERT(ret != nullptr); + return ret; +#elif defined(GPR_HAS_ALIGNED_MALLOC) + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + void* ret = _aligned_malloc(size, alignment); + GPR_ASSERT(ret != nullptr); + return ret; +#elif defined(GPR_HAS_POSIX_MEMALIGN) + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + GPR_DEBUG_ASSERT(alignment % sizeof(void*) == 0); + void* ret = nullptr; + GPR_ASSERT(posix_memalign(&ret, alignment, size) == 0); + return ret; +#else + return aligned_alloc_with_gpr_malloc(size, alignment); +#endif +} + +static void platform_free_aligned(void* ptr) { +#if defined(GPR_HAS_ALIGNED_ALLOC) || defined(GPR_HAS_POSIX_MEMALIGN) + free(ptr); +#elif defined(GPR_HAS_ALIGNED_MALLOC) + _aligned_free(ptr); +#else + aligned_free_with_gpr_malloc(ptr); +#endif +} + +static gpr_allocation_functions g_alloc_functions = { + malloc, zalloc_with_calloc, realloc, + free, platform_malloc_aligned, platform_free_aligned}; gpr_allocation_functions gpr_get_allocation_functions() { return g_alloc_functions; @@ -47,6 +101,12 @@ void gpr_set_allocation_functions(gpr_allocation_functions functions) { if (functions.zalloc_fn == nullptr) { functions.zalloc_fn = zalloc_with_gpr_malloc; } + GPR_ASSERT((functions.aligned_alloc_fn == nullptr) == + (functions.aligned_free_fn == nullptr)); + if (functions.aligned_alloc_fn == nullptr) { + functions.aligned_alloc_fn = aligned_alloc_with_gpr_malloc; + functions.aligned_free_fn = aligned_free_with_gpr_malloc; + } g_alloc_functions = functions; } @@ -88,12 +148,12 @@ void* gpr_realloc(void* p, size_t size) { } void* gpr_malloc_aligned(size_t size, size_t alignment) { - GPR_ASSERT(((alignment - 1) & alignment) == 0); // Must be power of 2. - size_t extra = alignment - 1 + sizeof(void*); - void* p = gpr_malloc(size + extra); - void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); - ret[-1] = p; - return (void*)ret; + GPR_TIMER_SCOPE("gpr_malloc_aligned", 0); + if (size == 0) return nullptr; + return g_alloc_functions.aligned_alloc_fn(size, alignment); } -void gpr_free_aligned(void* ptr) { gpr_free((static_cast(ptr))[-1]); } +void gpr_free_aligned(void* ptr) { + GPR_TIMER_SCOPE("gpr_free_aligned", 0); + g_alloc_functions.aligned_free_fn(ptr); +} diff --git a/src/core/lib/gpr/alloc.h b/src/core/lib/gpr/alloc.h index 762b51bf663..2493c87514d 100644 --- a/src/core/lib/gpr/alloc.h +++ b/src/core/lib/gpr/alloc.h @@ -25,4 +25,12 @@ #define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x) \ (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) +#define GPR_ROUND_UP_TO_CACHELINE_SIZE(x) \ + (((x) + GPR_CACHELINE_SIZE - 1u) & ~(GPR_CACHELINE_SIZE - 1u)) + +#define GPR_ROUND_UP_TO_SPECIFIED_SIZE(x, align) \ + (((x) + align - 1u) & ~(align - 1u)) + +void* gpr_malloc_cacheline(size_t size); + #endif /* GRPC_CORE_LIB_GPR_ALLOC_H */ diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h index b1b0c4a85cb..915cd5c528e 100644 --- a/src/core/lib/gprpp/arena.h +++ b/src/core/lib/gprpp/arena.h @@ -61,7 +61,7 @@ class Arena { GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); size_t begin = total_used_.FetchAdd(size, MemoryOrder::RELAXED); - if (begin + size <= initial_zone_size_) { + if (GPR_LIKELY(begin + size <= initial_zone_size_)) { return reinterpret_cast(this) + base_size + begin; } else { return AllocZone(size); diff --git a/test/core/gpr/alloc_test.cc b/test/core/gpr/alloc_test.cc index 0b110e2b77d..fb6bc9a0bdd 100644 --- a/test/core/gpr/alloc_test.cc +++ b/test/core/gpr/alloc_test.cc @@ -31,12 +31,21 @@ static void fake_free(void* addr) { *(static_cast(addr)) = static_cast(0xdeadd00d); } +static void* fake_aligned_malloc(size_t size, size_t alignment) { + return (void*)(size + alignment); +} + +static void fake_aligned_free(void* addr) { + *(static_cast(addr)) = static_cast(0xcafef00d); +} + static void test_custom_allocs() { const gpr_allocation_functions default_fns = gpr_get_allocation_functions(); intptr_t addr_to_free = 0; char* i; - gpr_allocation_functions fns = {fake_malloc, nullptr, fake_realloc, - fake_free}; + gpr_allocation_functions fns = {fake_malloc, nullptr, + fake_realloc, fake_free, + fake_aligned_malloc, fake_aligned_free}; gpr_set_allocation_functions(fns); GPR_ASSERT((void*)(size_t)0xdeadbeef == gpr_malloc(0xdeadbeef)); @@ -45,6 +54,11 @@ static void test_custom_allocs() { gpr_free(&addr_to_free); GPR_ASSERT(addr_to_free == (intptr_t)0xdeadd00d); + GPR_ASSERT((void*)(size_t)(0xdeadbeef + 64) == + gpr_malloc_aligned(0xdeadbeef, 64)); + gpr_free_aligned(&addr_to_free); + GPR_ASSERT(addr_to_free == (intptr_t)0xcafef00d); + /* Restore and check we don't get funky values and that we don't leak */ gpr_set_allocation_functions(default_fns); GPR_ASSERT((void*)sizeof(*i) != diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 787fb76e48b..11107f670fb 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -90,8 +90,12 @@ static void guard_free(void* vptr) { g_old_allocs.free_fn(ptr); } -struct gpr_allocation_functions g_guard_allocs = {guard_malloc, nullptr, - guard_realloc, guard_free}; +// NB: We do not specify guard_malloc_aligned/guard_free_aligned methods. Since +// they are null, calls to gpr_malloc_aligned/gpr_free_aligned are executed as a +// wrapper over gpr_malloc/gpr_free, which do use guard_malloc/guard_free, and +// thus there allocations are tracked as well. +struct gpr_allocation_functions g_guard_allocs = { + guard_malloc, nullptr, guard_realloc, guard_free, nullptr, nullptr}; void grpc_memory_counters_init() { memset(&g_memory_counters, 0, sizeof(g_memory_counters)); From a3fe7c0c908451deb04c3bb99a6b364b313467f6 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 29 Apr 2019 14:49:03 -0700 Subject: [PATCH 097/112] Renamed macros for memory alignment --- .../ext/filters/client_channel/subchannel.cc | 22 +++++----- src/core/lib/channel/channel_stack.cc | 43 ++++++++++--------- src/core/lib/gpr/alloc.cc | 2 +- src/core/lib/gpr/alloc.h | 14 +++--- src/core/lib/gprpp/arena.cc | 4 +- src/core/lib/gprpp/arena.h | 4 +- src/core/lib/surface/call.cc | 6 +-- src/core/lib/transport/transport.cc | 2 +- test/core/util/memory_counters.cc | 20 +++++---- 9 files changed, 61 insertions(+), 56 deletions(-) diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a284e692b09..873db8ef57c 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -66,12 +66,13 @@ #define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2 // Conversion between subchannel call and call stack. -#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ - (grpc_call_stack*)((char*)(call) + \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) -#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ - (SubchannelCall*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall))) +#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ + (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ + sizeof(SubchannelCall))) +#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \ + (SubchannelCall*)(((char*)(call_stack)) - \ + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ + sizeof(SubchannelCall))) namespace grpc_core { @@ -151,10 +152,10 @@ RefCountedPtr ConnectedSubchannel::CreateCall( size_t ConnectedSubchannel::GetInitialCallSizeEstimate( size_t parent_data_size) const { size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(SubchannelCall)); if (parent_data_size > 0) { allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + parent_data_size; } else { allocation_size += channel_stack_->call_stack_size; @@ -178,8 +179,9 @@ void SubchannelCall::StartTransportStreamOpBatch( void* SubchannelCall::GetParentData() { grpc_channel_stack* chanstk = connected_subchannel_->channel_stack(); - return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size); + return (char*)this + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(SubchannelCall)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(chanstk->call_stack_size); } grpc_call_stack* SubchannelCall::GetCallStack() { diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc index df956c7176c..7dfabbb0a1c 100644 --- a/src/core/lib/channel/channel_stack.cc +++ b/src/core/lib/channel/channel_stack.cc @@ -47,9 +47,9 @@ grpc_core::TraceFlag grpc_trace_channel(false, "channel"); size_t grpc_channel_stack_size(const grpc_channel_filter** filters, size_t filter_count) { /* always need the header, and size for the channel elements */ - size_t size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * - sizeof(grpc_channel_element)); + size_t size = GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_channel_stack)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( + filter_count * sizeof(grpc_channel_element)); size_t i; GPR_ASSERT((GPR_MAX_ALIGNMENT & (GPR_MAX_ALIGNMENT - 1)) == 0 && @@ -57,18 +57,18 @@ size_t grpc_channel_stack_size(const grpc_channel_filter** filters, /* add the size for each filter */ for (i = 0; i < filter_count; i++) { - size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); + size += GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); } return size; } -#define CHANNEL_ELEMS_FROM_STACK(stk) \ - ((grpc_channel_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ +#define CHANNEL_ELEMS_FROM_STACK(stk) \ + ((grpc_channel_element*)((char*)(stk) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ sizeof(grpc_channel_stack)))) -#define CALL_ELEMS_FROM_STACK(stk) \ - ((grpc_call_element*)((char*)(stk) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ +#define CALL_ELEMS_FROM_STACK(stk) \ + ((grpc_call_element*)((char*)(stk) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( \ sizeof(grpc_call_stack)))) grpc_channel_element* grpc_channel_stack_element( @@ -92,8 +92,9 @@ grpc_error* grpc_channel_stack_init( const grpc_channel_args* channel_args, grpc_transport* optional_transport, const char* name, grpc_channel_stack* stack) { size_t call_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filter_count * + sizeof(grpc_call_element)); grpc_channel_element* elems; grpc_channel_element_args args; char* user_data; @@ -104,8 +105,8 @@ grpc_error* grpc_channel_stack_init( name); elems = CHANNEL_ELEMS_FROM_STACK(stack); user_data = (reinterpret_cast(elems)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * - sizeof(grpc_channel_element)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filter_count * + sizeof(grpc_channel_element)); /* init per-filter data */ grpc_error* first_error = GRPC_ERROR_NONE; @@ -126,8 +127,9 @@ grpc_error* grpc_channel_stack_init( } } user_data += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); - call_size += GPR_ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); + call_size += + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); } GPR_ASSERT(user_data > (char*)stack); @@ -162,8 +164,9 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack, GRPC_STREAM_REF_INIT(&elem_args->call_stack->refcount, initial_refs, destroy, destroy_arg, "CALL_STACK"); call_elems = CALL_ELEMS_FROM_STACK(elem_args->call_stack); - user_data = (reinterpret_cast(call_elems)) + - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); + user_data = + (reinterpret_cast(call_elems)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); /* init per-filter data */ grpc_error* first_error = GRPC_ERROR_NONE; @@ -171,8 +174,8 @@ grpc_error* grpc_call_stack_init(grpc_channel_stack* channel_stack, call_elems[i].filter = channel_elems[i].filter; call_elems[i].channel_data = channel_elems[i].channel_data; call_elems[i].call_data = user_data; - user_data += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); + user_data += GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE( + call_elems[i].filter->sizeof_call_data); } for (size_t i = 0; i < count; i++) { grpc_error* error = @@ -242,11 +245,11 @@ grpc_channel_stack* grpc_channel_stack_from_top_element( grpc_channel_element* elem) { return reinterpret_cast( reinterpret_cast(elem) - - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_channel_stack))); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_channel_stack))); } grpc_call_stack* grpc_call_stack_from_top_element(grpc_call_element* elem) { return reinterpret_cast( reinterpret_cast(elem) - - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack))); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call_stack))); } diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index b601ad79f79..0d9f6f7120e 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -56,7 +56,7 @@ static void aligned_free_with_gpr_malloc(void* ptr) { static void* platform_malloc_aligned(size_t size, size_t alignment) { #if defined(GPR_HAS_ALIGNED_ALLOC) - size = GPR_ROUND_UP_TO_SPECIFIED_SIZE(size, alignment); + size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size, alignment); void* ret = aligned_alloc(alignment, size); GPR_ASSERT(ret != nullptr); return ret; diff --git a/src/core/lib/gpr/alloc.h b/src/core/lib/gpr/alloc.h index 2493c87514d..c77fbeaca49 100644 --- a/src/core/lib/gpr/alloc.h +++ b/src/core/lib/gpr/alloc.h @@ -22,15 +22,13 @@ #include /// Given a size, round up to the next multiple of sizeof(void*). -#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x) \ - (((x) + GPR_MAX_ALIGNMENT - 1u) & ~(GPR_MAX_ALIGNMENT - 1u)) +#define GPR_ROUND_UP_TO_ALIGNMENT_SIZE(x, align) \ + (((x) + (align)-1u) & ~((align)-1u)) -#define GPR_ROUND_UP_TO_CACHELINE_SIZE(x) \ - (((x) + GPR_CACHELINE_SIZE - 1u) & ~(GPR_CACHELINE_SIZE - 1u)) - -#define GPR_ROUND_UP_TO_SPECIFIED_SIZE(x, align) \ - (((x) + align - 1u) & ~(align - 1u)) +#define GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(x) \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE((x), GPR_MAX_ALIGNMENT) -void* gpr_malloc_cacheline(size_t size); +#define GPR_ROUND_UP_TO_CACHELINE_SIZE(x) \ + GPR_ROUND_UP_TO_ALIGNMENT_SIZE((x), GPR_CACHELINE_SIZE) #endif /* GRPC_CORE_LIB_GPR_ALLOC_H */ diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc index 5c344db4e35..e1c7b292f8c 100644 --- a/src/core/lib/gprpp/arena.cc +++ b/src/core/lib/gprpp/arena.cc @@ -67,7 +67,7 @@ Arena* Arena::Create(size_t initial_size) { Pair Arena::CreateWithAlloc(size_t initial_size, size_t alloc_size) { static constexpr size_t base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(Arena)); auto* new_arena = new (ArenaStorage(initial_size)) Arena(initial_size, alloc_size); void* first_alloc = reinterpret_cast(new_arena) + base_size; @@ -88,7 +88,7 @@ void* Arena::AllocZone(size_t size) { // sizing hysteresis (that is, most calls should have a large enough initial // zone and will not need to grow the arena). static constexpr size_t zone_base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Zone)); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(Zone)); size_t alloc_size = zone_base_size + size; Zone* z = new (gpr_malloc_aligned(alloc_size, GPR_MAX_ALIGNMENT)) Zone(); { diff --git a/src/core/lib/gprpp/arena.h b/src/core/lib/gprpp/arena.h index 915cd5c528e..6c646c5871d 100644 --- a/src/core/lib/gprpp/arena.h +++ b/src/core/lib/gprpp/arena.h @@ -58,8 +58,8 @@ class Arena { // Allocate \a size bytes from the arena. void* Alloc(size_t size) { static constexpr size_t base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(Arena)); - size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(Arena)); + size = GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(size); size_t begin = total_used_.FetchAdd(size, MemoryOrder::RELAXED); if (GPR_LIKELY(begin + size <= initial_zone_size_)) { return reinterpret_cast(this) + base_size + begin; diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index bd140021c96..0a26872a9ea 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -260,10 +260,10 @@ grpc_core::TraceFlag grpc_compression_trace(false, "compression"); #define CALL_STACK_FROM_CALL(call) \ (grpc_call_stack*)((char*)(call) + \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call))) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call))) #define CALL_FROM_CALL_STACK(call_stack) \ (grpc_call*)(((char*)(call_stack)) - \ - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call))) + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call))) #define CALL_ELEM_FROM_CALL(call, idx) \ grpc_call_stack_element(CALL_STACK_FROM_CALL(call), idx) @@ -329,7 +329,7 @@ grpc_error* grpc_call_create(const grpc_call_create_args* args, size_t initial_size = grpc_channel_get_call_size_estimate(args->channel); GRPC_STATS_INC_CALL_INITIAL_SIZE(initial_size); size_t call_and_stack_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call)) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_call)) + channel_stack->call_stack_size; size_t call_alloc_size = call_and_stack_size + (args->parent ? sizeof(child_call) : 0); diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc index 29c1e561891..40870657b84 100644 --- a/src/core/lib/transport/transport.cc +++ b/src/core/lib/transport/transport.cc @@ -115,7 +115,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from, } size_t grpc_transport_stream_size(grpc_transport* transport) { - return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream); + return GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(transport->vtable->sizeof_stream); } void grpc_transport_destroy(grpc_transport* transport) { diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc index 11107f670fb..60d22b18309 100644 --- a/test/core/util/memory_counters.cc +++ b/test/core/util/memory_counters.cc @@ -54,9 +54,10 @@ static void* guard_malloc(size_t size) { NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); void* ptr = g_old_allocs.malloc_fn( - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)) + size); *static_cast(ptr) = size; - return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); + return static_cast(ptr) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)); } static void* guard_realloc(void* vptr, size_t size) { @@ -67,23 +68,24 @@ static void* guard_realloc(void* vptr, size_t size) { guard_free(vptr); return nullptr; } - void* ptr = - static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); + void* ptr = static_cast(vptr) - + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); ptr = g_old_allocs.realloc_fn( - ptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size); + ptr, GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)) + size); *static_cast(ptr) = size; - return static_cast(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)); + return static_cast(ptr) + + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size)); } static void guard_free(void* vptr) { if (vptr == nullptr) return; - void* ptr = - static_cast(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t)); + void* ptr = static_cast(vptr) - + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(size_t)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -*static_cast(ptr)); NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); @@ -93,7 +95,7 @@ static void guard_free(void* vptr) { // NB: We do not specify guard_malloc_aligned/guard_free_aligned methods. Since // they are null, calls to gpr_malloc_aligned/gpr_free_aligned are executed as a // wrapper over gpr_malloc/gpr_free, which do use guard_malloc/guard_free, and -// thus there allocations are tracked as well. +// thus their allocations are tracked as well. struct gpr_allocation_functions g_guard_allocs = { guard_malloc, nullptr, guard_realloc, guard_free, nullptr, nullptr}; From e1a96b83471e229909890ebd9f9b7cf3d8d1edec Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Mon, 29 Apr 2019 15:20:31 -0700 Subject: [PATCH 098/112] Fixed non-debug build warning --- src/core/lib/gpr/alloc.cc | 2 ++ src/core/lib/gprpp/arena.cc | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index 0d9f6f7120e..b12b7d8534d 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -34,12 +34,14 @@ static void* zalloc_with_gpr_malloc(size_t sz) { return p; } +#ifndef NDEBUG static constexpr bool is_power_of_two(size_t value) { // 2^N = 100000...000 // 2^N - 1 = 011111...111 // (2^N) && ((2^N)-1)) = 0 return (value & (value - 1)) == 0; } +#endif static void* aligned_alloc_with_gpr_malloc(size_t size, size_t alignment) { GPR_DEBUG_ASSERT(is_power_of_two(alignment)); diff --git a/src/core/lib/gprpp/arena.cc b/src/core/lib/gprpp/arena.cc index e1c7b292f8c..2623ae870a1 100644 --- a/src/core/lib/gprpp/arena.cc +++ b/src/core/lib/gprpp/arena.cc @@ -35,8 +35,8 @@ namespace { void* ArenaStorage(size_t initial_size) { static constexpr size_t base_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); - initial_size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(initial_size); + GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(sizeof(grpc_core::Arena)); + initial_size = GPR_ROUND_UP_TO_MAX_ALIGNMENT_SIZE(initial_size); size_t alloc_size = base_size + initial_size; static constexpr size_t alignment = (GPR_CACHELINE_SIZE > GPR_MAX_ALIGNMENT && From 50b5240d0a9cf0002049982d8a84cce675b0f691 Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Mon, 29 Apr 2019 17:47:56 -0700 Subject: [PATCH 099/112] Revert "Merge pull request #18859 from grpc/internal_py_proto_library" This reverts commit 5b720f19c17d623b1b42f9089108295e25f89d88, reversing changes made to a64ae3c0d54903aa27fcf27296d7bc6c67d1e192. --- .gitignore | 1 - WORKSPACE | 7 + bazel/generate_cc.bzl | 202 +++++++---------- bazel/grpc_python_deps.bzl | 14 +- bazel/protobuf.bzl | 84 -------- bazel/python_rules.bzl | 203 ------------------ examples/BUILD | 12 +- examples/python/errors/client.py | 4 +- examples/python/errors/server.py | 4 +- .../test/_error_handling_example_test.py | 2 +- examples/python/multiprocessing/BUILD | 17 +- .../wait_for_ready/wait_for_ready_example.py | 11 +- src/proto/grpc/channelz/BUILD | 5 - src/proto/grpc/health/v1/BUILD | 5 - src/proto/grpc/reflection/v1alpha/BUILD | 5 - src/proto/grpc/testing/BUILD | 41 ++-- src/proto/grpc/testing/proto2/BUILD.bazel | 30 ++- .../grpc_channelz/v1/BUILD.bazel | 26 ++- .../grpc_health/v1/BUILD.bazel | 19 +- .../grpc_reflection/v1alpha/BUILD.bazel | 17 +- .../grpcio_tests/tests/reflection/BUILD.bazel | 1 - tools/distrib/bazel_style.cfg | 4 - tools/distrib/format_bazel.sh | 39 ---- .../linux/grpc_bazel_build_in_docker.sh | 3 +- .../linux/grpc_python_bazel_test_in_docker.sh | 13 +- 25 files changed, 209 insertions(+), 560 deletions(-) delete mode 100644 bazel/protobuf.bzl delete mode 100644 bazel/python_rules.bzl delete mode 100644 tools/distrib/bazel_style.cfg delete mode 100755 tools/distrib/format_bazel.sh diff --git a/.gitignore b/.gitignore index 7b4c5d36cb4..0d2647e61b6 100644 --- a/.gitignore +++ b/.gitignore @@ -115,7 +115,6 @@ bazel-genfiles bazel-grpc bazel-out bazel-testlogs -bazel_format_virtual_environment/ # Debug output gdb.txt diff --git a/WORKSPACE b/WORKSPACE index 2db3c5db2ff..fcf5b5d6d10 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -18,6 +18,13 @@ register_toolchains( "//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows", ) +# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. +git_repository( + name = "org_pubref_rules_protobuf", + remote = "https://github.com/ghostwriternr/rules_protobuf", + tag = "v0.8.2.1-alpha", +) + git_repository( name = "io_bazel_rules_python", commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 82f5cbad310..8f30c84f6b9 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -4,132 +4,81 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ -load( - "//bazel:protobuf.bzl", - "get_include_protoc_args", - "get_plugin_args", - "get_proto_root", - "proto_path_to_generated_filename", -) - -_GRPC_PROTO_HEADER_FMT = "{}.grpc.pb.h" -_GRPC_PROTO_SRC_FMT = "{}.grpc.pb.cc" -_GRPC_PROTO_MOCK_HEADER_FMT = "{}_mock.grpc.pb.h" -_PROTO_HEADER_FMT = "{}.pb.h" -_PROTO_SRC_FMT = "{}.pb.cc" - -def _strip_package_from_path(label_package, path): - if len(label_package) == 0: - return path - if not path.startswith(label_package + "/"): - fail("'{}' does not lie within '{}'.".format(path, label_package)) - return path[len(label_package + "/"):] +def generate_cc_impl(ctx): + """Implementation of the generate_cc rule.""" + protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] + includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports] + outs = [] + # label_len is length of the path from WORKSPACE root to the location of this build file + label_len = 0 + # proto_root is the directory relative to which generated include paths should be + proto_root = "" + if ctx.label.package: + # The +1 is for the trailing slash. + label_len += len(ctx.label.package) + 1 + if ctx.label.workspace_root: + label_len += len(ctx.label.workspace_root) + 1 + proto_root = "/" + ctx.label.workspace_root -def _join_directories(directories): - massaged_directories = [directory for directory in directories if len(directory) != 0] - return "/".join(massaged_directories) + if ctx.executable.plugin: + outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos] + outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos] + if ctx.attr.generate_mocks: + outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] + else: + outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos] + outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos] + out_files = [ctx.actions.declare_file(out) for out in outs] + dir_out = str(ctx.genfiles_dir.path + proto_root) -def generate_cc_impl(ctx): - """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] - includes = [ - f - for src in ctx.attr.srcs - for f in src.proto.transitive_imports - ] - outs = [] - proto_root = get_proto_root( - ctx.label.workspace_root, - ) + arguments = [] + if ctx.executable.plugin: + arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] + flags = list(ctx.attr.flags) + if ctx.attr.generate_mocks: + flags.append("generate_mock_code=true") + arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] + tools = [ctx.executable.plugin] + else: + arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] + tools = [] - label_package = _join_directories([ctx.label.workspace_root, ctx.label.package]) - if ctx.executable.plugin: - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _GRPC_PROTO_HEADER_FMT, - ) - for proto in protos - ] - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _GRPC_PROTO_SRC_FMT, - ) - for proto in protos - ] - if ctx.attr.generate_mocks: - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _GRPC_PROTO_MOCK_HEADER_FMT, - ) - for proto in protos - ] + # Import protos relative to their workspace root so that protoc prints the + # right include paths. + for include in includes: + directory = include.path + if directory.startswith("external"): + external_sep = directory.find("/") + repository_sep = directory.find("/", external_sep + 1) + arguments += ["--proto_path=" + directory[:repository_sep]] else: - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _PROTO_HEADER_FMT, - ) - for proto in protos - ] - outs += [ - proto_path_to_generated_filename( - _strip_package_from_path(label_package, proto.path), - _PROTO_SRC_FMT, - ) - for proto in protos - ] - out_files = [ctx.actions.declare_file(out) for out in outs] - dir_out = str(ctx.genfiles_dir.path + proto_root) + arguments += ["--proto_path=."] + # Include the output directory so that protoc puts the generated code in the + # right directory. + arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] + arguments += [proto.path for proto in protos] - arguments = [] - if ctx.executable.plugin: - arguments += get_plugin_args( - ctx.executable.plugin, - ctx.attr.flags, - dir_out, - ctx.attr.generate_mocks, - ) - tools = [ctx.executable.plugin] + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/com_google_protobuf/src/google/protobuf": + print("Error: Only @com_google_protobuf//:well_known_protos is supported") else: - arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - tools = [] - - arguments += get_include_protoc_args(includes) + # f points to "external/com_google_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] - # Include the output directory so that protoc puts the generated code in the - # right directory. - arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] - arguments += [proto.path for proto in protos] + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, + ) - # create a list of well known proto files if the argument is non-None - well_known_proto_files = [] - if ctx.attr.well_known_protos: - f = ctx.attr.well_known_protos.files.to_list()[0].dirname - if f != "external/com_google_protobuf/src/google/protobuf": - print( - "Error: Only @com_google_protobuf//:well_known_protos is supported", - ) - else: - # f points to "external/com_google_protobuf/src/google/protobuf" - # add -I argument to protoc so it knows where to look for the proto files. - arguments += ["-I{0}".format(f + "/../..")] - well_known_proto_files = [ - f - for f in ctx.attr.well_known_protos.files - ] - - ctx.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = ctx.executable._protoc, - arguments = arguments, - ) - - return struct(files = depset(out_files)) + return struct(files=depset(out_files)) _generate_cc = rule( attrs = { @@ -147,8 +96,10 @@ _generate_cc = rule( mandatory = False, allow_empty = True, ), - "well_known_protos": attr.label(mandatory = False), - "generate_mocks": attr.bool( + "well_known_protos" : attr.label( + mandatory = False, + ), + "generate_mocks" : attr.bool( default = False, mandatory = False, ), @@ -164,10 +115,7 @@ _generate_cc = rule( ) def generate_cc(well_known_protos, **kwargs): - if well_known_protos: - _generate_cc( - well_known_protos = "@com_google_protobuf//:well_known_protos", - **kwargs - ) - else: - _generate_cc(**kwargs) + if well_known_protos: + _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) + else: + _generate_cc(**kwargs) diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl index 91438f3927b..ec3df19e03a 100644 --- a/bazel/grpc_python_deps.bzl +++ b/bazel/grpc_python_deps.bzl @@ -1,8 +1,16 @@ load("//third_party/py:python_configure.bzl", "python_configure") load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") load("@grpc_python_dependencies//:requirements.bzl", "pip_install") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") def grpc_python_deps(): - python_configure(name = "local_config_python") - pip_repositories() - pip_install() + # TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional. + if hasattr(native, "http_archive"): + python_configure(name = "local_config_python") + pip_repositories() + pip_install() + py_proto_repositories() + else: + print("Building Python gRPC with bazel 23.0+ is disabled pending " + + "resolution of https://github.com/grpc/grpc/issues/18256.") + diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl deleted file mode 100644 index bddd0d70c7f..00000000000 --- a/bazel/protobuf.bzl +++ /dev/null @@ -1,84 +0,0 @@ -"""Utility functions for generating protobuf code.""" - -_PROTO_EXTENSION = ".proto" - -def get_proto_root(workspace_root): - """Gets the root protobuf directory. - - Args: - workspace_root: context.label.workspace_root - - Returns: - The directory relative to which generated include paths should be. - """ - if workspace_root: - return "/{}".format(workspace_root) - else: - return "" - -def _strip_proto_extension(proto_filename): - if not proto_filename.endswith(_PROTO_EXTENSION): - fail('"{}" does not end with "{}"'.format( - proto_filename, - _PROTO_EXTENSION, - )) - return proto_filename[:-len(_PROTO_EXTENSION)] - -def proto_path_to_generated_filename(proto_path, fmt_str): - """Calculates the name of a generated file for a protobuf path. - - For example, "examples/protos/helloworld.proto" might map to - "helloworld.pb.h". - - Args: - proto_path: The path to the .proto file. - fmt_str: A format string used to calculate the generated filename. For - example, "{}.pb.h" might be used to calculate a C++ header filename. - - Returns: - The generated filename. - """ - return fmt_str.format(_strip_proto_extension(proto_path)) - -def _get_include_directory(include): - directory = include.path - if directory.startswith("external"): - external_separator = directory.find("/") - repository_separator = directory.find("/", external_separator + 1) - return directory[:repository_separator] - else: - return "." - -def get_include_protoc_args(includes): - """Returns protoc args that imports protos relative to their import root. - - Args: - includes: A list of included proto files. - - Returns: - A list of arguments to be passed to protoc. For example, ["--proto_path=."]. - """ - return [ - "--proto_path={}".format(_get_include_directory(include)) - for include in includes - ] - -def get_plugin_args(plugin, flags, dir_out, generate_mocks): - """Returns arguments configuring protoc to use a plugin for a language. - - Args: - plugin: An executable file to run as the protoc plugin. - flags: The plugin flags to be passed to protoc. - dir_out: The output directory for the plugin. - generate_mocks: A bool indicating whether to generate mocks. - - Returns: - A list of protoc arguments configuring the plugin. - """ - augmented_flags = list(flags) - if generate_mocks: - augmented_flags.append("generate_mock_code=true") - return [ - "--plugin=protoc-gen-PLUGIN=" + plugin.path, - "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out, - ] diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl deleted file mode 100644 index bf6b4bec8d2..00000000000 --- a/bazel/python_rules.bzl +++ /dev/null @@ -1,203 +0,0 @@ -"""Generates and compiles Python gRPC stubs from proto_library rules.""" - -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load( - "//bazel:protobuf.bzl", - "get_include_protoc_args", - "get_plugin_args", - "get_proto_root", - "proto_path_to_generated_filename", -) - -_GENERATED_PROTO_FORMAT = "{}_pb2.py" -_GENERATED_GRPC_PROTO_FORMAT = "{}_pb2_grpc.py" - -def _get_staged_proto_file(context, source_file): - if source_file.dirname == context.label.package: - return source_file - else: - copied_proto = context.actions.declare_file(source_file.basename) - context.actions.run_shell( - inputs = [source_file], - outputs = [copied_proto], - command = "cp {} {}".format(source_file.path, copied_proto.path), - mnemonic = "CopySourceProto", - ) - return copied_proto - -def _generate_py_impl(context): - protos = [] - for src in context.attr.deps: - for file in src.proto.direct_sources: - protos.append(_get_staged_proto_file(context, file)) - includes = [ - file - for src in context.attr.deps - for file in src.proto.transitive_imports - ] - proto_root = get_proto_root(context.label.workspace_root) - format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) - out_files = [ - context.actions.declare_file( - proto_path_to_generated_filename( - proto.basename, - format_str, - ), - ) - for proto in protos - ] - - arguments = [] - tools = [context.executable._protoc] - if context.executable.plugin: - arguments += get_plugin_args( - context.executable.plugin, - context.attr.flags, - context.genfiles_dir.path, - False, - ) - tools += [context.executable.plugin] - else: - arguments += [ - "--python_out={}:{}".format( - ",".join(context.attr.flags), - context.genfiles_dir.path, - ), - ] - - arguments += get_include_protoc_args(includes) - arguments += [ - "--proto_path={}".format(context.genfiles_dir.path) - for proto in protos - ] - for proto in protos: - massaged_path = proto.path - if massaged_path.startswith(context.genfiles_dir.path): - massaged_path = proto.path[len(context.genfiles_dir.path) + 1:] - arguments.append(massaged_path) - - well_known_proto_files = [] - if context.attr.well_known_protos: - well_known_proto_directory = context.attr.well_known_protos.files.to_list( - )[0].dirname - - arguments += ["-I{}".format(well_known_proto_directory + "/../..")] - well_known_proto_files = context.attr.well_known_protos.files.to_list() - - context.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = context.executable._protoc, - arguments = arguments, - mnemonic = "ProtocInvocation", - ) - return struct(files = depset(out_files)) - -__generate_py = rule( - attrs = { - "deps": attr.label_list( - mandatory = True, - allow_empty = False, - providers = ["proto"], - ), - "plugin": attr.label( - executable = True, - providers = ["files_to_run"], - cfg = "host", - ), - "flags": attr.string_list( - mandatory = False, - allow_empty = True, - ), - "well_known_protos": attr.label(mandatory = False), - "_protoc": attr.label( - default = Label("//external:protocol_compiler"), - executable = True, - cfg = "host", - ), - }, - output_to_genfiles = True, - implementation = _generate_py_impl, -) - -def _generate_py(well_known_protos, **kwargs): - if well_known_protos: - __generate_py( - well_known_protos = "@com_google_protobuf//:well_known_protos", - **kwargs - ) - else: - __generate_py(**kwargs) - -_WELL_KNOWN_PROTO_LIBS = [ - "@com_google_protobuf//:any_proto", - "@com_google_protobuf//:api_proto", - "@com_google_protobuf//:compiler_plugin_proto", - "@com_google_protobuf//:descriptor_proto", - "@com_google_protobuf//:duration_proto", - "@com_google_protobuf//:empty_proto", - "@com_google_protobuf//:field_mask_proto", - "@com_google_protobuf//:source_context_proto", - "@com_google_protobuf//:struct_proto", - "@com_google_protobuf//:timestamp_proto", - "@com_google_protobuf//:type_proto", - "@com_google_protobuf//:wrappers_proto", -] - -def py_proto_library( - name, - deps, - well_known_protos = True, - proto_only = False, - **kwargs): - """Generate python code for a protobuf. - - Args: - name: The name of the target. - deps: A list of dependencies. Must contain a single element. - well_known_protos: A bool indicating whether or not to include well-known - protos. - proto_only: A bool indicating whether to generate vanilla protobuf code - or to also generate gRPC code. - """ - if len(deps) > 1: - fail("The supported length of 'deps' is 1.") - - codegen_target = "_{}_codegen".format(name) - codegen_grpc_target = "_{}_grpc_codegen".format(name) - - well_known_proto_rules = _WELL_KNOWN_PROTO_LIBS if well_known_protos else [] - - _generate_py( - name = codegen_target, - deps = deps, - well_known_protos = well_known_protos, - **kwargs - ) - - if not proto_only: - _generate_py( - name = codegen_grpc_target, - deps = deps, - plugin = "//:grpc_python_plugin", - well_known_protos = well_known_protos, - **kwargs - ) - - native.py_library( - name = name, - srcs = [ - ":{}".format(codegen_grpc_target), - ":{}".format(codegen_target), - ], - deps = [requirement("protobuf")], - **kwargs - ) - else: - native.py_library( - name = name, - srcs = [":{}".format(codegen_target), ":{}".format(codegen_target)], - deps = [requirement("protobuf")], - **kwargs - ) diff --git a/examples/BUILD b/examples/BUILD index d5fb6903d7c..d2b39b87f4d 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -16,8 +16,9 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) +load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") -load("//bazel:python_rules.bzl", "py_proto_library") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -44,14 +45,11 @@ grpc_proto_library( srcs = ["protos/keyvaluestore.proto"], ) -proto_library( - name = "helloworld_proto_descriptor", - srcs = ["protos/helloworld.proto"], -) - py_proto_library( name = "py_helloworld", - deps = [":helloworld_proto_descriptor"], + protos = ["protos/helloworld.proto"], + with_grpc = True, + deps = [requirement('protobuf'),], ) cc_binary( diff --git a/examples/python/errors/client.py b/examples/python/errors/client.py index c762d798dc2..a79b8fce1bd 100644 --- a/examples/python/errors/client.py +++ b/examples/python/errors/client.py @@ -20,8 +20,8 @@ import grpc from grpc_status import rpc_status from google.rpc import error_details_pb2 -from examples import helloworld_pb2 -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/errors/server.py b/examples/python/errors/server.py index 50d4a2ac671..f49586b848a 100644 --- a/examples/python/errors/server.py +++ b/examples/python/errors/server.py @@ -24,8 +24,8 @@ from grpc_status import rpc_status from google.protobuf import any_pb2 from google.rpc import code_pb2, status_pb2, error_details_pb2 -from examples import helloworld_pb2 -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py index 9eb81ba3742..a79ca45e2a1 100644 --- a/examples/python/errors/test/_error_handling_example_test.py +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -26,7 +26,7 @@ import logging import grpc -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2_grpc from examples.python.errors import client as error_handling_client from examples.python.errors import server as error_handling_server diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 0e135f471f2..6de1e947d85 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -15,17 +15,12 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("//bazel:python_rules.bzl", "py_proto_library") - -proto_library( - name = "prime_proto", - srcs = ["prime.proto"] -) +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") py_proto_library( - name = "prime_proto_pb2", - deps = [":prime_proto"], - well_known_protos = False, + name = "prime_proto", + protos = ["prime.proto",], + deps = [requirement("protobuf")], ) py_binary( @@ -34,7 +29,7 @@ py_binary( srcs = ["client.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto_pb2", + ":prime_proto", ], default_python_version = "PY3", ) @@ -45,7 +40,7 @@ py_binary( srcs = ["server.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto_pb2" + ":prime_proto" ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index a0f076e894a..7c16b9bd4a1 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -22,8 +22,8 @@ import threading import grpc -from examples import helloworld_pb2 -from examples import helloworld_pb2_grpc +from examples.protos import helloworld_pb2 +from examples.protos import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.INFO) @@ -33,13 +33,10 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @contextmanager def get_free_loopback_tcp_port(): - if socket.has_ipv6: - tcp_socket = socket.socket(socket.AF_INET6) - else: - tcp_socket = socket.socket(socket.AF_INET) + tcp_socket = socket.socket(socket.AF_INET6) tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() - yield "localhost:%s" % (address_tuple[1]) + yield "[::1]:%s" % (address_tuple[1]) tcp_socket.close() diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index 1d80ec23af1..b6b485e3e8d 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -25,11 +25,6 @@ grpc_proto_library( well_known_protos = True, ) -proto_library( - name = "channelz_proto_descriptors", - srcs = ["channelz.proto"], -) - filegroup( name = "channelz_proto_file", srcs = [ diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index fc58e8a1770..38a7d992e06 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -23,11 +23,6 @@ grpc_proto_library( srcs = ["health.proto"], ) -proto_library( - name = "health_proto_descriptor", - srcs = ["health.proto"], -) - filegroup( name = "health_proto_file", srcs = [ diff --git a/src/proto/grpc/reflection/v1alpha/BUILD b/src/proto/grpc/reflection/v1alpha/BUILD index 5424c0d867e..4d919d029ee 100644 --- a/src/proto/grpc/reflection/v1alpha/BUILD +++ b/src/proto/grpc/reflection/v1alpha/BUILD @@ -23,11 +23,6 @@ grpc_proto_library( srcs = ["reflection.proto"], ) -proto_library( - name = "reflection_proto_descriptor", - srcs = ["reflection.proto"], -) - filegroup( name = "reflection_proto_file", srcs = [ diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 16e47d81061..9876d5160a1 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -16,7 +16,7 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("//bazel:python_rules.bzl", "py_proto_library") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") grpc_package(name = "testing", visibility = "public") @@ -61,14 +61,13 @@ grpc_proto_library( has_services = False, ) -proto_library( - name = "empty_proto_descriptor", - srcs = ["empty.proto"], -) - py_proto_library( name = "py_empty_proto", - deps = [":empty_proto_descriptor"], + protos = ["empty.proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) grpc_proto_library( @@ -77,14 +76,13 @@ grpc_proto_library( has_services = False, ) -proto_library( - name = "messages_proto_descriptor", - srcs = ["messages.proto"], -) - py_proto_library( name = "py_messages_proto", - deps = [":messages_proto_descriptor"], + protos = ["messages.proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) grpc_proto_library( @@ -146,19 +144,16 @@ grpc_proto_library( ], ) -proto_library( - name = "test_proto_descriptor", - srcs = ["test.proto"], - deps = [ - ":empty_proto_descriptor", - ":messages_proto_descriptor", - ], -) - py_proto_library( name = "py_test_proto", + protos = ["test.proto",], + with_grpc = True, deps = [ - ":test_proto_descriptor", + requirement('protobuf'), + ], + proto_deps = [ + ":py_empty_proto", + ":py_messages_proto", ] ) diff --git a/src/proto/grpc/testing/proto2/BUILD.bazel b/src/proto/grpc/testing/proto2/BUILD.bazel index e939c523a64..c4c4f004efb 100644 --- a/src/proto/grpc/testing/proto2/BUILD.bazel +++ b/src/proto/grpc/testing/proto2/BUILD.bazel @@ -1,32 +1,30 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -load("//bazel:python_rules.bzl", "py_proto_library") - -proto_library( - name = "empty2_proto_descriptor", - srcs = ["empty2.proto"], -) py_proto_library( name = "empty2_proto", - deps = [ - ":empty2_proto_descriptor", + protos = [ + "empty2.proto", ], -) - -proto_library( - name = "empty2_extensions_proto_descriptor", - srcs = ["empty2_extensions.proto"], + with_grpc = True, deps = [ - ":empty2_proto_descriptor", - ] + requirement('protobuf'), + ], ) py_proto_library( name = "empty2_extensions_proto", + protos = [ + "empty2_extensions.proto", + ], + proto_deps = [ + ":empty2_proto", + ], + with_grpc = True, deps = [ - ":empty2_extensions_proto_descriptor", + requirement('protobuf'), ], ) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel index eccc166577d..aae8cedb760 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -1,10 +1,30 @@ -load("//bazel:python_rules.bzl", "py_proto_library") +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + package(default_visibility = ["//visibility:public"]) +genrule( + name = "mv_channelz_proto", + srcs = [ + "//src/proto/grpc/channelz:channelz_proto_file", + ], + outs = ["channelz.proto",], + cmd = "cp $< $@", +) + py_proto_library( name = "py_channelz_proto", - well_known_protos = True, - deps = ["//src/proto/grpc/channelz:channelz_proto_descriptors"], + protos = ["mv_channelz_proto",], + imports = [ + "external/com_google_protobuf/src/", + ], + inputs = [ + "@com_google_protobuf//:well_known_protos", + ], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) py_library( diff --git a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel index 9e4fff34581..ce3121fa90e 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel +++ b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel @@ -1,9 +1,24 @@ -load("//bazel:python_rules.bzl", "py_proto_library") +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") + package(default_visibility = ["//visibility:public"]) +genrule( + name = "mv_health_proto", + srcs = [ + "//src/proto/grpc/health/v1:health_proto_file", + ], + outs = ["health.proto",], + cmd = "cp $< $@", +) + py_proto_library( name = "py_health_proto", - deps = ["//src/proto/grpc/health/v1:health_proto_descriptor",], + protos = [":mv_health_proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) py_library( diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel index 6aaa4dd3bdd..3a2ba263715 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel @@ -1,11 +1,24 @@ -load("//bazel:python_rules.bzl", "py_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) +genrule( + name = "mv_reflection_proto", + srcs = [ + "//src/proto/grpc/reflection/v1alpha:reflection_proto_file", + ], + outs = ["reflection.proto",], + cmd = "cp $< $@", +) + py_proto_library( name = "py_reflection_proto", - deps = ["//src/proto/grpc/reflection/v1alpha:reflection_proto_descriptor",], + protos = [":mv_reflection_proto",], + with_grpc = True, + deps = [ + requirement('protobuf'), + ], ) py_library( diff --git a/src/python/grpcio_tests/tests/reflection/BUILD.bazel b/src/python/grpcio_tests/tests/reflection/BUILD.bazel index b635b721631..c0efb0b7cef 100644 --- a/src/python/grpcio_tests/tests/reflection/BUILD.bazel +++ b/src/python/grpcio_tests/tests/reflection/BUILD.bazel @@ -14,7 +14,6 @@ py_test( "//src/python/grpcio_tests/tests/unit:test_common", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing/proto2:empty2_extensions_proto", - "//src/proto/grpc/testing/proto2:empty2_proto", requirement('protobuf'), ], imports=["../../",], diff --git a/tools/distrib/bazel_style.cfg b/tools/distrib/bazel_style.cfg deleted file mode 100644 index a5a1fea4aba..00000000000 --- a/tools/distrib/bazel_style.cfg +++ /dev/null @@ -1,4 +0,0 @@ -[style] -based_on_style = google -allow_split_before_dict_value = False -spaces_around_default_or_named_assign = True diff --git a/tools/distrib/format_bazel.sh b/tools/distrib/format_bazel.sh deleted file mode 100755 index ee230118efb..00000000000 --- a/tools/distrib/format_bazel.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# Copyright 2019 The gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set=-ex - -VIRTUAL_ENV=bazel_format_virtual_environment - -CONFIG_PATH="$(dirname ${0})/bazel_style.cfg" - -python -m virtualenv ${VIRTUAL_ENV} -PYTHON=${VIRTUAL_ENV}/bin/python -"$PYTHON" -m pip install --upgrade pip==10.0.1 -"$PYTHON" -m pip install --upgrade futures -"$PYTHON" -m pip install yapf==0.20.0 - -pushd "$(dirname "${0}")/../.." -FILES=$(find . -path ./third_party -prune -o -name '*.bzl' -print) -echo "${FILES}" | xargs "$PYTHON" -m yapf -i --style="${CONFIG_PATH}" - -if ! which buildifier &>/dev/null; then - echo 'buildifer must be installed.' >/dev/stderr - exit 1 -fi - -echo "${FILES}" | xargs buildifier --type=bzl - -popd diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 24598f43f02..3dd0167b7c0 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,4 +24,5 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... +#TODO(yfen): add back examples/... to build targets once python rules issues are resolved +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index d844cff7f9a..3ca4673ca08 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -23,9 +23,10 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc (cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') -cd /var/local/git/grpc/test -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... -bazel clean --expunge -bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 +#cd /var/local/git/grpc/test +#bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +#bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +#bazel clean --expunge +#bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +#bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... From 9073d6d5b56ccd1f4bbb836dbd0c9ae77386cfa7 Mon Sep 17 00:00:00 2001 From: John Luo Date: Tue, 30 Apr 2019 00:26:57 -0700 Subject: [PATCH 100/112] Migrate interceptor types for server-side interceptors --- .../Interceptors/ClientInterceptorContext.cs | 0 .../Interceptors/Interceptor.cs | 0 src/csharp/Grpc.Core/ForwardedTypes.cs | 10 ++++++---- 3 files changed, 6 insertions(+), 4 deletions(-) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Interceptors/ClientInterceptorContext.cs (100%) rename src/csharp/{Grpc.Core => Grpc.Core.Api}/Interceptors/Interceptor.cs (100%) diff --git a/src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs b/src/csharp/Grpc.Core.Api/Interceptors/ClientInterceptorContext.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/ClientInterceptorContext.cs rename to src/csharp/Grpc.Core.Api/Interceptors/ClientInterceptorContext.cs diff --git a/src/csharp/Grpc.Core/Interceptors/Interceptor.cs b/src/csharp/Grpc.Core.Api/Interceptors/Interceptor.cs similarity index 100% rename from src/csharp/Grpc.Core/Interceptors/Interceptor.cs rename to src/csharp/Grpc.Core.Api/Interceptors/Interceptor.cs diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index 3df44d167be..8b42cae3890 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -32,16 +32,18 @@ using Grpc.Core.Utils; [assembly:TypeForwardedToAttribute(typeof(AuthContext))] [assembly:TypeForwardedToAttribute(typeof(AsyncAuthInterceptor))] [assembly:TypeForwardedToAttribute(typeof(AuthInterceptorContext))] -[assembly: TypeForwardedToAttribute(typeof(CallCredentials))] -[assembly: TypeForwardedToAttribute(typeof(CallFlags))] -[assembly: TypeForwardedToAttribute(typeof(CallInvoker))] -[assembly: TypeForwardedToAttribute(typeof(CallOptions))] +[assembly:TypeForwardedToAttribute(typeof(CallCredentials))] +[assembly:TypeForwardedToAttribute(typeof(CallFlags))] +[assembly:TypeForwardedToAttribute(typeof(CallInvoker))] +[assembly:TypeForwardedToAttribute(typeof(CallOptions))] +[assembly:TypeForwardedToAttribute(typeof(ClientInterceptorContext<,>))] [assembly:TypeForwardedToAttribute(typeof(ContextPropagationOptions))] [assembly:TypeForwardedToAttribute(typeof(ContextPropagationToken))] [assembly:TypeForwardedToAttribute(typeof(DeserializationContext))] [assembly:TypeForwardedToAttribute(typeof(IAsyncStreamReader<>))] [assembly:TypeForwardedToAttribute(typeof(IAsyncStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(IClientStreamWriter<>))] +[assembly:TypeForwardedToAttribute(typeof(Interceptor))] [assembly:TypeForwardedToAttribute(typeof(IServerStreamWriter<>))] [assembly:TypeForwardedToAttribute(typeof(Marshaller<>))] [assembly:TypeForwardedToAttribute(typeof(Marshallers))] From f52a743e34f68de26d681eb7b6d3436d72b96645 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 30 Apr 2019 01:43:23 -0700 Subject: [PATCH 101/112] Missed using --- src/csharp/Grpc.Core/ForwardedTypes.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Core/ForwardedTypes.cs b/src/csharp/Grpc.Core/ForwardedTypes.cs index 8b42cae3890..ab5f5a87c67 100644 --- a/src/csharp/Grpc.Core/ForwardedTypes.cs +++ b/src/csharp/Grpc.Core/ForwardedTypes.cs @@ -18,6 +18,7 @@ using System.Runtime.CompilerServices; using Grpc.Core; +using Grpc.Core.Interceptors; using Grpc.Core.Internal; using Grpc.Core.Utils; From 930cec4e27347a2cc852954917e0263b27d7480b Mon Sep 17 00:00:00 2001 From: Richard Belleville Date: Tue, 30 Apr 2019 11:17:11 -0700 Subject: [PATCH 102/112] Revert "Merge pull request #18912 from grpc/revert-bazel-changes" This reverts commit c9a259aa3a5a8081fc8de88108759db07d3a4379, reversing changes made to 9c882bc7253a91262d662409453c5fc70b019d20. --- .gitignore | 1 + WORKSPACE | 7 - bazel/generate_cc.bzl | 202 ++++++++++------- bazel/grpc_python_deps.bzl | 14 +- bazel/protobuf.bzl | 84 ++++++++ bazel/python_rules.bzl | 203 ++++++++++++++++++ examples/BUILD | 12 +- examples/python/errors/client.py | 4 +- examples/python/errors/server.py | 4 +- .../test/_error_handling_example_test.py | 2 +- examples/python/multiprocessing/BUILD | 17 +- .../wait_for_ready/wait_for_ready_example.py | 11 +- src/proto/grpc/channelz/BUILD | 5 + src/proto/grpc/health/v1/BUILD | 5 + src/proto/grpc/reflection/v1alpha/BUILD | 5 + src/proto/grpc/testing/BUILD | 41 ++-- src/proto/grpc/testing/proto2/BUILD.bazel | 30 +-- .../grpc_channelz/v1/BUILD.bazel | 26 +-- .../grpc_health/v1/BUILD.bazel | 19 +- .../grpc_reflection/v1alpha/BUILD.bazel | 17 +- .../grpcio_tests/tests/reflection/BUILD.bazel | 1 + tools/distrib/bazel_style.cfg | 4 + tools/distrib/format_bazel.sh | 39 ++++ .../linux/grpc_bazel_build_in_docker.sh | 3 +- .../linux/grpc_python_bazel_test_in_docker.sh | 13 +- 25 files changed, 560 insertions(+), 209 deletions(-) create mode 100644 bazel/protobuf.bzl create mode 100644 bazel/python_rules.bzl create mode 100644 tools/distrib/bazel_style.cfg create mode 100755 tools/distrib/format_bazel.sh diff --git a/.gitignore b/.gitignore index 0d2647e61b6..7b4c5d36cb4 100644 --- a/.gitignore +++ b/.gitignore @@ -115,6 +115,7 @@ bazel-genfiles bazel-grpc bazel-out bazel-testlogs +bazel_format_virtual_environment/ # Debug output gdb.txt diff --git a/WORKSPACE b/WORKSPACE index fcf5b5d6d10..2db3c5db2ff 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -18,13 +18,6 @@ register_toolchains( "//third_party/toolchains/bazel_0.23.2_rbe_windows:cc-toolchain-x64_windows", ) -# TODO(https://github.com/grpc/grpc/issues/18331): Move off of this dependency. -git_repository( - name = "org_pubref_rules_protobuf", - remote = "https://github.com/ghostwriternr/rules_protobuf", - tag = "v0.8.2.1-alpha", -) - git_repository( name = "io_bazel_rules_python", commit = "8b5d0683a7d878b28fffe464779c8a53659fc645", diff --git a/bazel/generate_cc.bzl b/bazel/generate_cc.bzl index 8f30c84f6b9..82f5cbad310 100644 --- a/bazel/generate_cc.bzl +++ b/bazel/generate_cc.bzl @@ -4,81 +4,132 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ -def generate_cc_impl(ctx): - """Implementation of the generate_cc rule.""" - protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] - includes = [f for src in ctx.attr.srcs for f in src.proto.transitive_imports] - outs = [] - # label_len is length of the path from WORKSPACE root to the location of this build file - label_len = 0 - # proto_root is the directory relative to which generated include paths should be - proto_root = "" - if ctx.label.package: - # The +1 is for the trailing slash. - label_len += len(ctx.label.package) + 1 - if ctx.label.workspace_root: - label_len += len(ctx.label.workspace_root) + 1 - proto_root = "/" + ctx.label.workspace_root +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GRPC_PROTO_HEADER_FMT = "{}.grpc.pb.h" +_GRPC_PROTO_SRC_FMT = "{}.grpc.pb.cc" +_GRPC_PROTO_MOCK_HEADER_FMT = "{}_mock.grpc.pb.h" +_PROTO_HEADER_FMT = "{}.pb.h" +_PROTO_SRC_FMT = "{}.pb.cc" - if ctx.executable.plugin: - outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.h" for proto in protos] - outs += [proto.path[label_len:-len(".proto")] + ".grpc.pb.cc" for proto in protos] - if ctx.attr.generate_mocks: - outs += [proto.path[label_len:-len(".proto")] + "_mock.grpc.pb.h" for proto in protos] - else: - outs += [proto.path[label_len:-len(".proto")] + ".pb.h" for proto in protos] - outs += [proto.path[label_len:-len(".proto")] + ".pb.cc" for proto in protos] - out_files = [ctx.actions.declare_file(out) for out in outs] - dir_out = str(ctx.genfiles_dir.path + proto_root) +def _strip_package_from_path(label_package, path): + if len(label_package) == 0: + return path + if not path.startswith(label_package + "/"): + fail("'{}' does not lie within '{}'.".format(path, label_package)) + return path[len(label_package + "/"):] - arguments = [] - if ctx.executable.plugin: - arguments += ["--plugin=protoc-gen-PLUGIN=" + ctx.executable.plugin.path] - flags = list(ctx.attr.flags) - if ctx.attr.generate_mocks: - flags.append("generate_mock_code=true") - arguments += ["--PLUGIN_out=" + ",".join(flags) + ":" + dir_out] - tools = [ctx.executable.plugin] - else: - arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] - tools = [] +def _join_directories(directories): + massaged_directories = [directory for directory in directories if len(directory) != 0] + return "/".join(massaged_directories) - # Import protos relative to their workspace root so that protoc prints the - # right include paths. - for include in includes: - directory = include.path - if directory.startswith("external"): - external_sep = directory.find("/") - repository_sep = directory.find("/", external_sep + 1) - arguments += ["--proto_path=" + directory[:repository_sep]] +def generate_cc_impl(ctx): + """Implementation of the generate_cc rule.""" + protos = [f for src in ctx.attr.srcs for f in src.proto.direct_sources] + includes = [ + f + for src in ctx.attr.srcs + for f in src.proto.transitive_imports + ] + outs = [] + proto_root = get_proto_root( + ctx.label.workspace_root, + ) + + label_package = _join_directories([ctx.label.workspace_root, ctx.label.package]) + if ctx.executable.plugin: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_SRC_FMT, + ) + for proto in protos + ] + if ctx.attr.generate_mocks: + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _GRPC_PROTO_MOCK_HEADER_FMT, + ) + for proto in protos + ] else: - arguments += ["--proto_path=."] - # Include the output directory so that protoc puts the generated code in the - # right directory. - arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] - arguments += [proto.path for proto in protos] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _PROTO_HEADER_FMT, + ) + for proto in protos + ] + outs += [ + proto_path_to_generated_filename( + _strip_package_from_path(label_package, proto.path), + _PROTO_SRC_FMT, + ) + for proto in protos + ] + out_files = [ctx.actions.declare_file(out) for out in outs] + dir_out = str(ctx.genfiles_dir.path + proto_root) - # create a list of well known proto files if the argument is non-None - well_known_proto_files = [] - if ctx.attr.well_known_protos: - f = ctx.attr.well_known_protos.files.to_list()[0].dirname - if f != "external/com_google_protobuf/src/google/protobuf": - print("Error: Only @com_google_protobuf//:well_known_protos is supported") + arguments = [] + if ctx.executable.plugin: + arguments += get_plugin_args( + ctx.executable.plugin, + ctx.attr.flags, + dir_out, + ctx.attr.generate_mocks, + ) + tools = [ctx.executable.plugin] else: - # f points to "external/com_google_protobuf/src/google/protobuf" - # add -I argument to protoc so it knows where to look for the proto files. - arguments += ["-I{0}".format(f + "/../..")] - well_known_proto_files = [f for f in ctx.attr.well_known_protos.files] + arguments += ["--cpp_out=" + ",".join(ctx.attr.flags) + ":" + dir_out] + tools = [] + + arguments += get_include_protoc_args(includes) - ctx.actions.run( - inputs = protos + includes + well_known_proto_files, - tools = tools, - outputs = out_files, - executable = ctx.executable._protoc, - arguments = arguments, - ) + # Include the output directory so that protoc puts the generated code in the + # right directory. + arguments += ["--proto_path={0}{1}".format(dir_out, proto_root)] + arguments += [proto.path for proto in protos] - return struct(files=depset(out_files)) + # create a list of well known proto files if the argument is non-None + well_known_proto_files = [] + if ctx.attr.well_known_protos: + f = ctx.attr.well_known_protos.files.to_list()[0].dirname + if f != "external/com_google_protobuf/src/google/protobuf": + print( + "Error: Only @com_google_protobuf//:well_known_protos is supported", + ) + else: + # f points to "external/com_google_protobuf/src/google/protobuf" + # add -I argument to protoc so it knows where to look for the proto files. + arguments += ["-I{0}".format(f + "/../..")] + well_known_proto_files = [ + f + for f in ctx.attr.well_known_protos.files + ] + + ctx.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = ctx.executable._protoc, + arguments = arguments, + ) + + return struct(files = depset(out_files)) _generate_cc = rule( attrs = { @@ -96,10 +147,8 @@ _generate_cc = rule( mandatory = False, allow_empty = True, ), - "well_known_protos" : attr.label( - mandatory = False, - ), - "generate_mocks" : attr.bool( + "well_known_protos": attr.label(mandatory = False), + "generate_mocks": attr.bool( default = False, mandatory = False, ), @@ -115,7 +164,10 @@ _generate_cc = rule( ) def generate_cc(well_known_protos, **kwargs): - if well_known_protos: - _generate_cc(well_known_protos="@com_google_protobuf//:well_known_protos", **kwargs) - else: - _generate_cc(**kwargs) + if well_known_protos: + _generate_cc( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + _generate_cc(**kwargs) diff --git a/bazel/grpc_python_deps.bzl b/bazel/grpc_python_deps.bzl index ec3df19e03a..91438f3927b 100644 --- a/bazel/grpc_python_deps.bzl +++ b/bazel/grpc_python_deps.bzl @@ -1,16 +1,8 @@ load("//third_party/py:python_configure.bzl", "python_configure") load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories") load("@grpc_python_dependencies//:requirements.bzl", "pip_install") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories") def grpc_python_deps(): - # TODO(https://github.com/grpc/grpc/issues/18256): Remove conditional. - if hasattr(native, "http_archive"): - python_configure(name = "local_config_python") - pip_repositories() - pip_install() - py_proto_repositories() - else: - print("Building Python gRPC with bazel 23.0+ is disabled pending " + - "resolution of https://github.com/grpc/grpc/issues/18256.") - + python_configure(name = "local_config_python") + pip_repositories() + pip_install() diff --git a/bazel/protobuf.bzl b/bazel/protobuf.bzl new file mode 100644 index 00000000000..bddd0d70c7f --- /dev/null +++ b/bazel/protobuf.bzl @@ -0,0 +1,84 @@ +"""Utility functions for generating protobuf code.""" + +_PROTO_EXTENSION = ".proto" + +def get_proto_root(workspace_root): + """Gets the root protobuf directory. + + Args: + workspace_root: context.label.workspace_root + + Returns: + The directory relative to which generated include paths should be. + """ + if workspace_root: + return "/{}".format(workspace_root) + else: + return "" + +def _strip_proto_extension(proto_filename): + if not proto_filename.endswith(_PROTO_EXTENSION): + fail('"{}" does not end with "{}"'.format( + proto_filename, + _PROTO_EXTENSION, + )) + return proto_filename[:-len(_PROTO_EXTENSION)] + +def proto_path_to_generated_filename(proto_path, fmt_str): + """Calculates the name of a generated file for a protobuf path. + + For example, "examples/protos/helloworld.proto" might map to + "helloworld.pb.h". + + Args: + proto_path: The path to the .proto file. + fmt_str: A format string used to calculate the generated filename. For + example, "{}.pb.h" might be used to calculate a C++ header filename. + + Returns: + The generated filename. + """ + return fmt_str.format(_strip_proto_extension(proto_path)) + +def _get_include_directory(include): + directory = include.path + if directory.startswith("external"): + external_separator = directory.find("/") + repository_separator = directory.find("/", external_separator + 1) + return directory[:repository_separator] + else: + return "." + +def get_include_protoc_args(includes): + """Returns protoc args that imports protos relative to their import root. + + Args: + includes: A list of included proto files. + + Returns: + A list of arguments to be passed to protoc. For example, ["--proto_path=."]. + """ + return [ + "--proto_path={}".format(_get_include_directory(include)) + for include in includes + ] + +def get_plugin_args(plugin, flags, dir_out, generate_mocks): + """Returns arguments configuring protoc to use a plugin for a language. + + Args: + plugin: An executable file to run as the protoc plugin. + flags: The plugin flags to be passed to protoc. + dir_out: The output directory for the plugin. + generate_mocks: A bool indicating whether to generate mocks. + + Returns: + A list of protoc arguments configuring the plugin. + """ + augmented_flags = list(flags) + if generate_mocks: + augmented_flags.append("generate_mock_code=true") + return [ + "--plugin=protoc-gen-PLUGIN=" + plugin.path, + "--PLUGIN_out=" + ",".join(augmented_flags) + ":" + dir_out, + ] diff --git a/bazel/python_rules.bzl b/bazel/python_rules.bzl new file mode 100644 index 00000000000..bf6b4bec8d2 --- /dev/null +++ b/bazel/python_rules.bzl @@ -0,0 +1,203 @@ +"""Generates and compiles Python gRPC stubs from proto_library rules.""" + +load("@grpc_python_dependencies//:requirements.bzl", "requirement") +load( + "//bazel:protobuf.bzl", + "get_include_protoc_args", + "get_plugin_args", + "get_proto_root", + "proto_path_to_generated_filename", +) + +_GENERATED_PROTO_FORMAT = "{}_pb2.py" +_GENERATED_GRPC_PROTO_FORMAT = "{}_pb2_grpc.py" + +def _get_staged_proto_file(context, source_file): + if source_file.dirname == context.label.package: + return source_file + else: + copied_proto = context.actions.declare_file(source_file.basename) + context.actions.run_shell( + inputs = [source_file], + outputs = [copied_proto], + command = "cp {} {}".format(source_file.path, copied_proto.path), + mnemonic = "CopySourceProto", + ) + return copied_proto + +def _generate_py_impl(context): + protos = [] + for src in context.attr.deps: + for file in src.proto.direct_sources: + protos.append(_get_staged_proto_file(context, file)) + includes = [ + file + for src in context.attr.deps + for file in src.proto.transitive_imports + ] + proto_root = get_proto_root(context.label.workspace_root) + format_str = (_GENERATED_GRPC_PROTO_FORMAT if context.executable.plugin else _GENERATED_PROTO_FORMAT) + out_files = [ + context.actions.declare_file( + proto_path_to_generated_filename( + proto.basename, + format_str, + ), + ) + for proto in protos + ] + + arguments = [] + tools = [context.executable._protoc] + if context.executable.plugin: + arguments += get_plugin_args( + context.executable.plugin, + context.attr.flags, + context.genfiles_dir.path, + False, + ) + tools += [context.executable.plugin] + else: + arguments += [ + "--python_out={}:{}".format( + ",".join(context.attr.flags), + context.genfiles_dir.path, + ), + ] + + arguments += get_include_protoc_args(includes) + arguments += [ + "--proto_path={}".format(context.genfiles_dir.path) + for proto in protos + ] + for proto in protos: + massaged_path = proto.path + if massaged_path.startswith(context.genfiles_dir.path): + massaged_path = proto.path[len(context.genfiles_dir.path) + 1:] + arguments.append(massaged_path) + + well_known_proto_files = [] + if context.attr.well_known_protos: + well_known_proto_directory = context.attr.well_known_protos.files.to_list( + )[0].dirname + + arguments += ["-I{}".format(well_known_proto_directory + "/../..")] + well_known_proto_files = context.attr.well_known_protos.files.to_list() + + context.actions.run( + inputs = protos + includes + well_known_proto_files, + tools = tools, + outputs = out_files, + executable = context.executable._protoc, + arguments = arguments, + mnemonic = "ProtocInvocation", + ) + return struct(files = depset(out_files)) + +__generate_py = rule( + attrs = { + "deps": attr.label_list( + mandatory = True, + allow_empty = False, + providers = ["proto"], + ), + "plugin": attr.label( + executable = True, + providers = ["files_to_run"], + cfg = "host", + ), + "flags": attr.string_list( + mandatory = False, + allow_empty = True, + ), + "well_known_protos": attr.label(mandatory = False), + "_protoc": attr.label( + default = Label("//external:protocol_compiler"), + executable = True, + cfg = "host", + ), + }, + output_to_genfiles = True, + implementation = _generate_py_impl, +) + +def _generate_py(well_known_protos, **kwargs): + if well_known_protos: + __generate_py( + well_known_protos = "@com_google_protobuf//:well_known_protos", + **kwargs + ) + else: + __generate_py(**kwargs) + +_WELL_KNOWN_PROTO_LIBS = [ + "@com_google_protobuf//:any_proto", + "@com_google_protobuf//:api_proto", + "@com_google_protobuf//:compiler_plugin_proto", + "@com_google_protobuf//:descriptor_proto", + "@com_google_protobuf//:duration_proto", + "@com_google_protobuf//:empty_proto", + "@com_google_protobuf//:field_mask_proto", + "@com_google_protobuf//:source_context_proto", + "@com_google_protobuf//:struct_proto", + "@com_google_protobuf//:timestamp_proto", + "@com_google_protobuf//:type_proto", + "@com_google_protobuf//:wrappers_proto", +] + +def py_proto_library( + name, + deps, + well_known_protos = True, + proto_only = False, + **kwargs): + """Generate python code for a protobuf. + + Args: + name: The name of the target. + deps: A list of dependencies. Must contain a single element. + well_known_protos: A bool indicating whether or not to include well-known + protos. + proto_only: A bool indicating whether to generate vanilla protobuf code + or to also generate gRPC code. + """ + if len(deps) > 1: + fail("The supported length of 'deps' is 1.") + + codegen_target = "_{}_codegen".format(name) + codegen_grpc_target = "_{}_grpc_codegen".format(name) + + well_known_proto_rules = _WELL_KNOWN_PROTO_LIBS if well_known_protos else [] + + _generate_py( + name = codegen_target, + deps = deps, + well_known_protos = well_known_protos, + **kwargs + ) + + if not proto_only: + _generate_py( + name = codegen_grpc_target, + deps = deps, + plugin = "//:grpc_python_plugin", + well_known_protos = well_known_protos, + **kwargs + ) + + native.py_library( + name = name, + srcs = [ + ":{}".format(codegen_grpc_target), + ":{}".format(codegen_target), + ], + deps = [requirement("protobuf")], + **kwargs + ) + else: + native.py_library( + name = name, + srcs = [":{}".format(codegen_target), ":{}".format(codegen_target)], + deps = [requirement("protobuf")], + **kwargs + ) diff --git a/examples/BUILD b/examples/BUILD index d2b39b87f4d..d5fb6903d7c 100644 --- a/examples/BUILD +++ b/examples/BUILD @@ -16,9 +16,8 @@ licenses(["notice"]) # 3-clause BSD package(default_visibility = ["//visibility:public"]) -load("@grpc_python_dependencies//:requirements.bzl", "requirement") load("//bazel:grpc_build_system.bzl", "grpc_proto_library") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_proto_library( name = "auth_sample", @@ -45,11 +44,14 @@ grpc_proto_library( srcs = ["protos/keyvaluestore.proto"], ) +proto_library( + name = "helloworld_proto_descriptor", + srcs = ["protos/helloworld.proto"], +) + py_proto_library( name = "py_helloworld", - protos = ["protos/helloworld.proto"], - with_grpc = True, - deps = [requirement('protobuf'),], + deps = [":helloworld_proto_descriptor"], ) cc_binary( diff --git a/examples/python/errors/client.py b/examples/python/errors/client.py index a79b8fce1bd..c762d798dc2 100644 --- a/examples/python/errors/client.py +++ b/examples/python/errors/client.py @@ -20,8 +20,8 @@ import grpc from grpc_status import rpc_status from google.rpc import error_details_pb2 -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) diff --git a/examples/python/errors/server.py b/examples/python/errors/server.py index f49586b848a..50d4a2ac671 100644 --- a/examples/python/errors/server.py +++ b/examples/python/errors/server.py @@ -24,8 +24,8 @@ from grpc_status import rpc_status from google.protobuf import any_pb2 from google.rpc import code_pb2, status_pb2, error_details_pb2 -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _ONE_DAY_IN_SECONDS = 60 * 60 * 24 diff --git a/examples/python/errors/test/_error_handling_example_test.py b/examples/python/errors/test/_error_handling_example_test.py index a79ca45e2a1..9eb81ba3742 100644 --- a/examples/python/errors/test/_error_handling_example_test.py +++ b/examples/python/errors/test/_error_handling_example_test.py @@ -26,7 +26,7 @@ import logging import grpc -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2_grpc from examples.python.errors import client as error_handling_client from examples.python.errors import server as error_handling_server diff --git a/examples/python/multiprocessing/BUILD b/examples/python/multiprocessing/BUILD index 6de1e947d85..0e135f471f2 100644 --- a/examples/python/multiprocessing/BUILD +++ b/examples/python/multiprocessing/BUILD @@ -15,12 +15,17 @@ # limitations under the License. load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") -py_proto_library( +proto_library( name = "prime_proto", - protos = ["prime.proto",], - deps = [requirement("protobuf")], + srcs = ["prime.proto"] +) + +py_proto_library( + name = "prime_proto_pb2", + deps = [":prime_proto"], + well_known_protos = False, ) py_binary( @@ -29,7 +34,7 @@ py_binary( srcs = ["client.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto", + ":prime_proto_pb2", ], default_python_version = "PY3", ) @@ -40,7 +45,7 @@ py_binary( srcs = ["server.py"], deps = [ "//src/python/grpcio/grpc:grpcio", - ":prime_proto" + ":prime_proto_pb2" ] + select({ "//conditions:default": [requirement("futures")], "//:python3": [], diff --git a/examples/python/wait_for_ready/wait_for_ready_example.py b/examples/python/wait_for_ready/wait_for_ready_example.py index 7c16b9bd4a1..a0f076e894a 100644 --- a/examples/python/wait_for_ready/wait_for_ready_example.py +++ b/examples/python/wait_for_ready/wait_for_ready_example.py @@ -22,8 +22,8 @@ import threading import grpc -from examples.protos import helloworld_pb2 -from examples.protos import helloworld_pb2_grpc +from examples import helloworld_pb2 +from examples import helloworld_pb2_grpc _LOGGER = logging.getLogger(__name__) _LOGGER.setLevel(logging.INFO) @@ -33,10 +33,13 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @contextmanager def get_free_loopback_tcp_port(): - tcp_socket = socket.socket(socket.AF_INET6) + if socket.has_ipv6: + tcp_socket = socket.socket(socket.AF_INET6) + else: + tcp_socket = socket.socket(socket.AF_INET) tcp_socket.bind(('', 0)) address_tuple = tcp_socket.getsockname() - yield "[::1]:%s" % (address_tuple[1]) + yield "localhost:%s" % (address_tuple[1]) tcp_socket.close() diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD index b6b485e3e8d..1d80ec23af1 100644 --- a/src/proto/grpc/channelz/BUILD +++ b/src/proto/grpc/channelz/BUILD @@ -25,6 +25,11 @@ grpc_proto_library( well_known_protos = True, ) +proto_library( + name = "channelz_proto_descriptors", + srcs = ["channelz.proto"], +) + filegroup( name = "channelz_proto_file", srcs = [ diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD index 38a7d992e06..fc58e8a1770 100644 --- a/src/proto/grpc/health/v1/BUILD +++ b/src/proto/grpc/health/v1/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["health.proto"], ) +proto_library( + name = "health_proto_descriptor", + srcs = ["health.proto"], +) + filegroup( name = "health_proto_file", srcs = [ diff --git a/src/proto/grpc/reflection/v1alpha/BUILD b/src/proto/grpc/reflection/v1alpha/BUILD index 4d919d029ee..5424c0d867e 100644 --- a/src/proto/grpc/reflection/v1alpha/BUILD +++ b/src/proto/grpc/reflection/v1alpha/BUILD @@ -23,6 +23,11 @@ grpc_proto_library( srcs = ["reflection.proto"], ) +proto_library( + name = "reflection_proto_descriptor", + srcs = ["reflection.proto"], +) + filegroup( name = "reflection_proto_file", srcs = [ diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD index 9876d5160a1..16e47d81061 100644 --- a/src/proto/grpc/testing/BUILD +++ b/src/proto/grpc/testing/BUILD @@ -16,7 +16,7 @@ licenses(["notice"]) # Apache v2 load("//bazel:grpc_build_system.bzl", "grpc_proto_library", "grpc_package") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") +load("//bazel:python_rules.bzl", "py_proto_library") grpc_package(name = "testing", visibility = "public") @@ -61,13 +61,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "empty_proto_descriptor", + srcs = ["empty.proto"], +) + py_proto_library( name = "py_empty_proto", - protos = ["empty.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":empty_proto_descriptor"], ) grpc_proto_library( @@ -76,13 +77,14 @@ grpc_proto_library( has_services = False, ) +proto_library( + name = "messages_proto_descriptor", + srcs = ["messages.proto"], +) + py_proto_library( name = "py_messages_proto", - protos = ["messages.proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = [":messages_proto_descriptor"], ) grpc_proto_library( @@ -144,16 +146,19 @@ grpc_proto_library( ], ) +proto_library( + name = "test_proto_descriptor", + srcs = ["test.proto"], + deps = [ + ":empty_proto_descriptor", + ":messages_proto_descriptor", + ], +) + py_proto_library( name = "py_test_proto", - protos = ["test.proto",], - with_grpc = True, deps = [ - requirement('protobuf'), - ], - proto_deps = [ - ":py_empty_proto", - ":py_messages_proto", + ":test_proto_descriptor", ] ) diff --git a/src/proto/grpc/testing/proto2/BUILD.bazel b/src/proto/grpc/testing/proto2/BUILD.bazel index c4c4f004efb..e939c523a64 100644 --- a/src/proto/grpc/testing/proto2/BUILD.bazel +++ b/src/proto/grpc/testing/proto2/BUILD.bazel @@ -1,30 +1,32 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) +load("//bazel:python_rules.bzl", "py_proto_library") + +proto_library( + name = "empty2_proto_descriptor", + srcs = ["empty2.proto"], +) py_proto_library( name = "empty2_proto", - protos = [ - "empty2.proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_proto_descriptor", ], ) +proto_library( + name = "empty2_extensions_proto_descriptor", + srcs = ["empty2_extensions.proto"], + deps = [ + ":empty2_proto_descriptor", + ] +) + py_proto_library( name = "empty2_extensions_proto", - protos = [ - "empty2_extensions.proto", - ], - proto_deps = [ - ":empty2_proto", - ], - with_grpc = True, deps = [ - requirement('protobuf'), + ":empty2_extensions_proto_descriptor", ], ) diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel index aae8cedb760..eccc166577d 100644 --- a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel +++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel @@ -1,30 +1,10 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_channelz_proto", - srcs = [ - "//src/proto/grpc/channelz:channelz_proto_file", - ], - outs = ["channelz.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_channelz_proto", - protos = ["mv_channelz_proto",], - imports = [ - "external/com_google_protobuf/src/", - ], - inputs = [ - "@com_google_protobuf//:well_known_protos", - ], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + well_known_protos = True, + deps = ["//src/proto/grpc/channelz:channelz_proto_descriptors"], ) py_library( diff --git a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel index ce3121fa90e..9e4fff34581 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel +++ b/src/python/grpcio_health_checking/grpc_health/v1/BUILD.bazel @@ -1,24 +1,9 @@ -load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") - +load("//bazel:python_rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_health_proto", - srcs = [ - "//src/proto/grpc/health/v1:health_proto_file", - ], - outs = ["health.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_health_proto", - protos = [":mv_health_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/health/v1:health_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel index 3a2ba263715..6aaa4dd3bdd 100644 --- a/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel +++ b/src/python/grpcio_reflection/grpc_reflection/v1alpha/BUILD.bazel @@ -1,24 +1,11 @@ +load("//bazel:python_rules.bzl", "py_proto_library") load("@grpc_python_dependencies//:requirements.bzl", "requirement") -load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") package(default_visibility = ["//visibility:public"]) -genrule( - name = "mv_reflection_proto", - srcs = [ - "//src/proto/grpc/reflection/v1alpha:reflection_proto_file", - ], - outs = ["reflection.proto",], - cmd = "cp $< $@", -) - py_proto_library( name = "py_reflection_proto", - protos = [":mv_reflection_proto",], - with_grpc = True, - deps = [ - requirement('protobuf'), - ], + deps = ["//src/proto/grpc/reflection/v1alpha:reflection_proto_descriptor",], ) py_library( diff --git a/src/python/grpcio_tests/tests/reflection/BUILD.bazel b/src/python/grpcio_tests/tests/reflection/BUILD.bazel index c0efb0b7cef..b635b721631 100644 --- a/src/python/grpcio_tests/tests/reflection/BUILD.bazel +++ b/src/python/grpcio_tests/tests/reflection/BUILD.bazel @@ -14,6 +14,7 @@ py_test( "//src/python/grpcio_tests/tests/unit:test_common", "//src/proto/grpc/testing:py_empty_proto", "//src/proto/grpc/testing/proto2:empty2_extensions_proto", + "//src/proto/grpc/testing/proto2:empty2_proto", requirement('protobuf'), ], imports=["../../",], diff --git a/tools/distrib/bazel_style.cfg b/tools/distrib/bazel_style.cfg new file mode 100644 index 00000000000..a5a1fea4aba --- /dev/null +++ b/tools/distrib/bazel_style.cfg @@ -0,0 +1,4 @@ +[style] +based_on_style = google +allow_split_before_dict_value = False +spaces_around_default_or_named_assign = True diff --git a/tools/distrib/format_bazel.sh b/tools/distrib/format_bazel.sh new file mode 100755 index 00000000000..ee230118efb --- /dev/null +++ b/tools/distrib/format_bazel.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright 2019 The gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set=-ex + +VIRTUAL_ENV=bazel_format_virtual_environment + +CONFIG_PATH="$(dirname ${0})/bazel_style.cfg" + +python -m virtualenv ${VIRTUAL_ENV} +PYTHON=${VIRTUAL_ENV}/bin/python +"$PYTHON" -m pip install --upgrade pip==10.0.1 +"$PYTHON" -m pip install --upgrade futures +"$PYTHON" -m pip install yapf==0.20.0 + +pushd "$(dirname "${0}")/../.." +FILES=$(find . -path ./third_party -prune -o -name '*.bzl' -print) +echo "${FILES}" | xargs "$PYTHON" -m yapf -i --style="${CONFIG_PATH}" + +if ! which buildifier &>/dev/null; then + echo 'buildifer must be installed.' >/dev/stderr + exit 1 +fi + +echo "${FILES}" | xargs buildifier --type=bzl + +popd diff --git a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh index 3dd0167b7c0..24598f43f02 100755 --- a/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh +++ b/tools/internal_ci/linux/grpc_bazel_build_in_docker.sh @@ -24,5 +24,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') cd /var/local/git/grpc -#TODO(yfen): add back examples/... to build targets once python rules issues are resolved -bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... +bazel build --spawn_strategy=standalone --genrule_strategy=standalone :all test/... examples/... diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh index 3ca4673ca08..d844cff7f9a 100755 --- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh +++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh @@ -23,10 +23,9 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc (cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ && git submodule update --init --reference /var/local/jenkins/grpc/${name} \ ${name}') -#TODO(yfen): temporarily disabled all python bazel tests due to incompatibility with bazel 0.23.2 -#cd /var/local/git/grpc/test -#bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -#bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... -#bazel clean --expunge -#bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... -#bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +cd /var/local/git/grpc/test +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... +bazel clean --expunge +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/... +bazel test --config=python3 --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //examples/python/... From 714a13c193c588967201132af4bb56f8cf47ded6 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 14:15:50 -0400 Subject: [PATCH 103/112] Initialize TCP write and error closures only once. We are initializing the closures in the hot path on every event. --- src/core/lib/iomgr/tcp_posix.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 30305a94f37..b140ae0ccae 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -271,16 +271,8 @@ static void notify_on_write(grpc_tcp* tcp) { if (grpc_tcp_trace.enabled()) { gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp); } - if (grpc_event_engine_run_in_background()) { - // If there is a polling engine always running in the background, there is - // no need to run the backup poller. - GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, - grpc_schedule_on_exec_ctx); - } else { + if (!grpc_event_engine_run_in_background()) { cover_self(tcp); - GRPC_CLOSURE_INIT(&tcp->write_done_closure, - tcp_drop_uncovered_then_handle_write, tcp, - grpc_schedule_on_exec_ctx); } grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure); } @@ -884,8 +876,6 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) { * ready. */ grpc_fd_set_readable(tcp->em_fd); grpc_fd_set_writable(tcp->em_fd); - GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp, - grpc_schedule_on_exec_ctx); grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure); } @@ -1248,6 +1238,16 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, tcp->tb_head = nullptr; GRPC_CLOSURE_INIT(&tcp->read_done_closure, tcp_handle_read, tcp, grpc_schedule_on_exec_ctx); + if (grpc_event_engine_run_in_background()) { + // If there is a polling engine always running in the background, there is + // no need to run the backup poller. + GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } else { + GRPC_CLOSURE_INIT(&tcp->write_done_closure, + tcp_drop_uncovered_then_handle_write, tcp, + grpc_schedule_on_exec_ctx); + } /* Always assume there is something on the queue to read. */ tcp->inq = 1; #ifdef GRPC_HAVE_TCP_INQ From 6b0806eae327afd05f58f9fc68783850ba98749a Mon Sep 17 00:00:00 2001 From: Karthik Ravi Shankar Date: Tue, 30 Apr 2019 11:22:04 -0700 Subject: [PATCH 104/112] more formatting changes --- include/grpcpp/server_impl.h | 6 +++--- src/cpp/server/server_cc.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/grpcpp/server_impl.h b/include/grpcpp/server_impl.h index 14b16a06f4e..46bacf81d26 100644 --- a/include/grpcpp/server_impl.h +++ b/include/grpcpp/server_impl.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -49,7 +50,6 @@ class ServerContext; namespace grpc_impl { -class HealthCheckServiceInterface; class ServerInitializer; /// Represents a gRPC server. @@ -99,7 +99,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { grpc_server* c_server(); /// Returns the health check service. - grpc_impl::HealthCheckServiceInterface* GetHealthCheckService() const { + grpc::HealthCheckServiceInterface* GetHealthCheckService() const { return health_check_service_.get(); } @@ -333,7 +333,7 @@ class Server : public grpc::ServerInterface, private grpc::GrpcLibraryCodegen { std::unique_ptr server_initializer_; - std::unique_ptr health_check_service_; + std::unique_ptr health_check_service_; bool health_check_service_disabled_; // When appropriate, use a default callback generic service to handle diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 31bdc553f8b..9c2b1ee13fc 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -753,9 +753,9 @@ class Server::CallbackRequest final : public Server::CallbackRequestBase { &server_->callback_unmatched_reqs_count_[method_index_], 1); grpc_metadata_array_init(&request_metadata_); ctx_.Setup(gpr_inf_future(GPR_CLOCK_REALTIME)); - handler_data_ = nullptr; request_payload_ = nullptr; request_ = nullptr; + handler_data_ = nullptr; request_status_ = grpc::Status(); } From 2cb63d859d69512a92685a19887ea7428c47bb9f Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 30 Apr 2019 20:29:42 +0200 Subject: [PATCH 105/112] split multilang jobs by language --- .../linux/grpc_basictests_csharp.cfg | 30 ++++++++++++++++++ .../linux/grpc_basictests_node.cfg | 30 ++++++++++++++++++ .../internal_ci/linux/grpc_basictests_php.cfg | 30 ++++++++++++++++++ .../linux/grpc_basictests_python.cfg | 30 ++++++++++++++++++ .../linux/grpc_basictests_ruby.cfg | 30 ++++++++++++++++++ .../macos/grpc_basictests_c_cpp.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_csharp.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_node.cfg | 31 +++++++++++++++++++ .../internal_ci/macos/grpc_basictests_php.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_python.cfg | 31 +++++++++++++++++++ .../macos/grpc_basictests_ruby.cfg | 31 +++++++++++++++++++ .../internal_ci/windows/grpc_basictests_c.cfg | 30 ++++++++++++++++++ .../windows/grpc_basictests_csharp.cfg | 30 ++++++++++++++++++ .../windows/grpc_basictests_python.cfg | 30 ++++++++++++++++++ 14 files changed, 426 insertions(+) create mode 100644 tools/internal_ci/linux/grpc_basictests_csharp.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_node.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_php.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_python.cfg create mode 100644 tools/internal_ci/linux/grpc_basictests_ruby.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_c_cpp.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_csharp.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_node.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_php.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_python.cfg create mode 100644 tools/internal_ci/macos/grpc_basictests_ruby.cfg create mode 100644 tools/internal_ci/windows/grpc_basictests_c.cfg create mode 100644 tools/internal_ci/windows/grpc_basictests_csharp.cfg create mode 100644 tools/internal_ci/windows/grpc_basictests_python.cfg diff --git a/tools/internal_ci/linux/grpc_basictests_csharp.cfg b/tools/internal_ci/linux/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..017e929beff --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux csharp --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_node.cfg b/tools/internal_ci/linux/grpc_basictests_node.cfg new file mode 100644 index 00000000000..d7b35a04719 --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_node.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux grpc-node --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_php.cfg b/tools/internal_ci/linux/grpc_basictests_php.cfg new file mode 100644 index 00000000000..80aa0dc87bb --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_php.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux php --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_python.cfg b/tools/internal_ci/linux/grpc_basictests_python.cfg new file mode 100644 index 00000000000..444dba9f4df --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux python --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/linux/grpc_basictests_ruby.cfg b/tools/internal_ci/linux/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..336aa469958 --- /dev/null +++ b/tools/internal_ci/linux/grpc_basictests_ruby.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_tests_matrix.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests linux ruby --inner_jobs 16 -j 2 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg new file mode 100644 index 00000000000..9783dd64673 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_c_cpp.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos corelang --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_csharp.cfg b/tools/internal_ci/macos/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..d3e04e71f71 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_csharp.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos csharp --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_node.cfg b/tools/internal_ci/macos/grpc_basictests_node.cfg new file mode 100644 index 00000000000..9dfd6a7b9e8 --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_node.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos grpc-node --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_php.cfg b/tools/internal_ci/macos/grpc_basictests_php.cfg new file mode 100644 index 00000000000..091f68efaba --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_php.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos php --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_python.cfg b/tools/internal_ci/macos/grpc_basictests_python.cfg new file mode 100644 index 00000000000..ae80ac317ff --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_python.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos python --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/macos/grpc_basictests_ruby.cfg b/tools/internal_ci/macos/grpc_basictests_ruby.cfg new file mode 100644 index 00000000000..3a28f97a54b --- /dev/null +++ b/tools/internal_ci/macos/grpc_basictests_ruby.cfg @@ -0,0 +1,31 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/macos/grpc_run_tests_matrix.sh" +gfile_resources: "/bigstore/grpc-testing-secrets/gcp_credentials/GrpcTesting-d0eeee2db331.json" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests macos ruby --internal_ci -j 1 --inner_jobs 4 --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_c.cfg b/tools/internal_ci/windows/grpc_basictests_c.cfg new file mode 100644 index 00000000000..150a28e3f89 --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_c.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows c -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_csharp.cfg b/tools/internal_ci/windows/grpc_basictests_csharp.cfg new file mode 100644 index 00000000000..17a362fb32a --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_csharp.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows csharp -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} diff --git a/tools/internal_ci/windows/grpc_basictests_python.cfg b/tools/internal_ci/windows/grpc_basictests_python.cfg new file mode 100644 index 00000000000..b0f6f6772d3 --- /dev/null +++ b/tools/internal_ci/windows/grpc_basictests_python.cfg @@ -0,0 +1,30 @@ +# Copyright 2019 The gRPC Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/windows/grpc_run_tests_matrix.bat" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "-f basictests windows python -j 1 --inner_jobs 8 --internal_ci --bq_result_table aggregate_results" +} From 058e90ef161e31d1f892b49c0ee6cb0ba3957e9e Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Tue, 30 Apr 2019 11:12:19 -0700 Subject: [PATCH 106/112] Tiny fix for combiner comment --- src/core/lib/iomgr/combiner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/iomgr/combiner.h b/src/core/lib/iomgr/combiner.h index 3c947bf9d64..b9274216993 100644 --- a/src/core/lib/iomgr/combiner.h +++ b/src/core/lib/iomgr/combiner.h @@ -31,7 +31,7 @@ // Provides serialized access to some resource. // Each action queued on a combiner is executed serially in a borrowed thread. // The actual thread executing actions may change over time (but there will only -// every be one at a time). +// ever be one at a time). // Initialize the lock, with an optional workqueue to shift load to when // necessary From dc148b6a303262124ac96a41a78e6bbd3770a83b Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 30 Apr 2019 10:29:11 -0700 Subject: [PATCH 107/112] Fix regression where we do not properly account for freed interned metadata. --- src/core/lib/transport/metadata.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/metadata.cc b/src/core/lib/transport/metadata.cc index e3b8d112795..7e0b2163246 100644 --- a/src/core/lib/transport/metadata.cc +++ b/src/core/lib/transport/metadata.cc @@ -211,7 +211,6 @@ void grpc_mdctx_global_shutdown() { mdtab_shard* shard = &g_shards[i]; gpr_mu_destroy(&shard->mu); gc_mdtab(shard); - /* TODO(ctiller): GPR_ASSERT(shard->count == 0); */ if (shard->count != 0) { gpr_log(GPR_DEBUG, "WARNING: %" PRIuPTR " metadata elements were leaked", shard->count); @@ -219,6 +218,7 @@ void grpc_mdctx_global_shutdown() { abort(); } } + GPR_DEBUG_ASSERT(shard->count == 0); gpr_free(shard->elems); } } @@ -251,7 +251,9 @@ static void gc_mdtab(mdtab_shard* shard) { GPR_TIMER_SCOPE("gc_mdtab", 0); size_t num_freed = 0; for (size_t i = 0; i < shard->capacity; ++i) { - num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); + intptr_t freed = InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); + num_freed += freed; + shard->count -= freed; } gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -static_cast(num_freed)); From 22c6e166c439481d5d5fa0990b8c59db92ec5152 Mon Sep 17 00:00:00 2001 From: Arjun Roy Date: Tue, 30 Apr 2019 11:49:34 -0700 Subject: [PATCH 108/112] Use platform align_malloc function when setting custom allocators and no override provided --- src/core/lib/gpr/alloc.cc | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/core/lib/gpr/alloc.cc b/src/core/lib/gpr/alloc.cc index b12b7d8534d..f79e645971a 100644 --- a/src/core/lib/gpr/alloc.cc +++ b/src/core/lib/gpr/alloc.cc @@ -43,21 +43,9 @@ static constexpr bool is_power_of_two(size_t value) { } #endif -static void* aligned_alloc_with_gpr_malloc(size_t size, size_t alignment) { - GPR_DEBUG_ASSERT(is_power_of_two(alignment)); - size_t extra = alignment - 1 + sizeof(void*); - void* p = gpr_malloc(size + extra); - void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); - ret[-1] = p; - return (void*)ret; -} - -static void aligned_free_with_gpr_malloc(void* ptr) { - gpr_free((static_cast(ptr))[-1]); -} - static void* platform_malloc_aligned(size_t size, size_t alignment) { #if defined(GPR_HAS_ALIGNED_ALLOC) + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size, alignment); void* ret = aligned_alloc(alignment, size); GPR_ASSERT(ret != nullptr); @@ -74,7 +62,12 @@ static void* platform_malloc_aligned(size_t size, size_t alignment) { GPR_ASSERT(posix_memalign(&ret, alignment, size) == 0); return ret; #else - return aligned_alloc_with_gpr_malloc(size, alignment); + GPR_DEBUG_ASSERT(is_power_of_two(alignment)); + size_t extra = alignment - 1 + sizeof(void*); + void* p = gpr_malloc(size + extra); + void** ret = (void**)(((uintptr_t)p + extra) & ~(alignment - 1)); + ret[-1] = p; + return (void*)ret; #endif } @@ -84,7 +77,7 @@ static void platform_free_aligned(void* ptr) { #elif defined(GPR_HAS_ALIGNED_MALLOC) _aligned_free(ptr); #else - aligned_free_with_gpr_malloc(ptr); + gpr_free((static_cast(ptr))[-1]); #endif } @@ -106,8 +99,8 @@ void gpr_set_allocation_functions(gpr_allocation_functions functions) { GPR_ASSERT((functions.aligned_alloc_fn == nullptr) == (functions.aligned_free_fn == nullptr)); if (functions.aligned_alloc_fn == nullptr) { - functions.aligned_alloc_fn = aligned_alloc_with_gpr_malloc; - functions.aligned_free_fn = aligned_free_with_gpr_malloc; + functions.aligned_alloc_fn = platform_malloc_aligned; + functions.aligned_free_fn = platform_free_aligned; } g_alloc_functions = functions; } From 1518ecbd76040fa1b9157a53e735c7e2e7c95c64 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Mon, 15 Apr 2019 10:48:30 -0700 Subject: [PATCH 109/112] Added new configuration system to core/grp. More generic configuration system is introduced in order to i) unify the way how modules access the configurations instead of using low-level get/setenv functions and ii) enable the customization for where configuration is stored. This could be extended to support flag, file, etc. Default configuration system uses environment variables as before so basically this is expected to work just as it did. This behavior can change by redefining GPR_GLOBAL_CONFIG_DEFINE_*type* macros. * Migrated configuration GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL GRPC_ABORT_ON_LEAKS GRPC_NOT_USE_SYSTEM_SSL_ROOTS --- BUILD | 5 + BUILD.gn | 9 ++ CMakeLists.txt | 77 ++++++++++ Makefile | 97 +++++++++++++ build.yaml | 23 +++ config.m4 | 1 + config.w32 | 1 + gRPC-C++.podspec | 8 ++ gRPC-Core.podspec | 9 ++ grpc.gemspec | 5 + grpc.gyp | 1 + package.xml | 5 + .../filters/client_channel/backup_poller.cc | 27 ++-- .../filters/client_channel/backup_poller.h | 3 + .../chttp2/transport/chttp2_plugin.cc | 13 +- src/core/lib/gpr/env.h | 3 + src/core/lib/gpr/env_linux.cc | 5 + src/core/lib/gpr/env_posix.cc | 5 + src/core/lib/gpr/env_windows.cc | 7 + src/core/lib/gpr/string.cc | 18 ++- src/core/lib/gpr/string.h | 6 +- src/core/lib/gprpp/global_config.h | 87 +++++++++++ src/core/lib/gprpp/global_config_custom.h | 29 ++++ src/core/lib/gprpp/global_config_env.cc | 135 ++++++++++++++++++ src/core/lib/gprpp/global_config_env.h | 131 +++++++++++++++++ src/core/lib/gprpp/global_config_generic.h | 44 ++++++ src/core/lib/iomgr/iomgr.cc | 10 +- .../security/security_connector/ssl_utils.cc | 12 +- src/python/grpcio/grpc_core_dependencies.py | 1 + test/core/gpr/env_test.cc | 14 ++ test/core/gpr/string_test.cc | 29 ++-- test/core/gprpp/BUILD | 26 ++++ test/core/gprpp/global_config_env_test.cc | 130 +++++++++++++++++ test/core/gprpp/global_config_test.cc | 65 +++++++++ test/cpp/end2end/async_end2end_test.cc | 3 +- test/cpp/end2end/client_lb_end2end_test.cc | 4 +- test/cpp/end2end/end2end_test.cc | 3 +- test/cpp/end2end/grpclb_end2end_test.cc | 4 +- test/cpp/end2end/xds_end2end_test.cc | 3 +- test/cpp/naming/resolver_component_test.cc | 5 +- tools/doxygen/Doxyfile.c++.internal | 4 + tools/doxygen/Doxyfile.core.internal | 5 + .../generated/sources_and_headers.json | 39 +++++ tools/run_tests/generated/tests.json | 48 +++++++ 44 files changed, 1096 insertions(+), 63 deletions(-) create mode 100644 src/core/lib/gprpp/global_config.h create mode 100644 src/core/lib/gprpp/global_config_custom.h create mode 100644 src/core/lib/gprpp/global_config_env.cc create mode 100644 src/core/lib/gprpp/global_config_env.h create mode 100644 src/core/lib/gprpp/global_config_generic.h create mode 100644 test/core/gprpp/global_config_env_test.cc create mode 100644 test/core/gprpp/global_config_test.cc diff --git a/BUILD b/BUILD index 58043459000..94f2e2a1b75 100644 --- a/BUILD +++ b/BUILD @@ -575,6 +575,7 @@ grpc_cc_library( "src/core/lib/gpr/wrap_memcpy.cc", "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -601,6 +602,10 @@ grpc_cc_library( "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", + "src/core/lib/gprpp/global_config.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", diff --git a/BUILD.gn b/BUILD.gn index 38b2f0e6502..f642f6af1c2 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -184,6 +184,11 @@ config("grpc_config") { "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.cc", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.cc", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -1170,6 +1175,10 @@ config("grpc_config") { "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/debug_location.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/inlined_vector.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b93ab08af4..da2326525da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -629,6 +629,8 @@ add_dependencies(buildtests_cxx error_details_test) add_dependencies(buildtests_cxx exception_test) add_dependencies(buildtests_cxx filter_end2end_test) add_dependencies(buildtests_cxx generic_end2end_test) +add_dependencies(buildtests_cxx global_config_env_test) +add_dependencies(buildtests_cxx global_config_test) add_dependencies(buildtests_cxx golden_file_test) add_dependencies(buildtests_cxx grpc_alts_credentials_options_test) add_dependencies(buildtests_cxx grpc_cli) @@ -873,6 +875,7 @@ add_library(gpr src/core/lib/gpr/wrap_memcpy.cc src/core/lib/gprpp/arena.cc src/core/lib/gprpp/fork.cc + src/core/lib/gprpp/global_config_env.cc src/core/lib/gprpp/thd_posix.cc src/core/lib/gprpp/thd_windows.cc src/core/lib/profiling/basic_timers.cc @@ -13422,6 +13425,80 @@ target_link_libraries(generic_end2end_test ) +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(global_config_env_test + test/core/gprpp/global_config_env_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(global_config_env_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(global_config_env_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr + grpc_test_util_unsecure + ${_gRPC_GFLAGS_LIBRARIES} +) + + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + +add_executable(global_config_test + test/core/gprpp/global_config_test.cc + third_party/googletest/googletest/src/gtest-all.cc + third_party/googletest/googlemock/src/gmock-all.cc +) + + +target_include_directories(global_config_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${_gRPC_SSL_INCLUDE_DIR} + PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} + PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} + PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} + PRIVATE ${_gRPC_CARES_INCLUDE_DIR} + PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} + PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} + PRIVATE third_party/googletest/googletest/include + PRIVATE third_party/googletest/googletest + PRIVATE third_party/googletest/googlemock/include + PRIVATE third_party/googletest/googlemock + PRIVATE ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(global_config_test + ${_gRPC_PROTOBUF_LIBRARIES} + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr + grpc_test_util_unsecure + ${_gRPC_GFLAGS_LIBRARIES} +) + + endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) diff --git a/Makefile b/Makefile index 700e789265e..2cf316590ec 100644 --- a/Makefile +++ b/Makefile @@ -1206,6 +1206,8 @@ error_details_test: $(BINDIR)/$(CONFIG)/error_details_test exception_test: $(BINDIR)/$(CONFIG)/exception_test filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test +global_config_env_test: $(BINDIR)/$(CONFIG)/global_config_env_test +global_config_test: $(BINDIR)/$(CONFIG)/global_config_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test grpc_alts_credentials_options_test: $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli @@ -1682,6 +1684,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/exception_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ + $(BINDIR)/$(CONFIG)/global_config_env_test \ + $(BINDIR)/$(CONFIG)/global_config_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -1826,6 +1830,8 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/exception_test \ $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ + $(BINDIR)/$(CONFIG)/global_config_env_test \ + $(BINDIR)/$(CONFIG)/global_config_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_alts_credentials_options_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ @@ -2318,6 +2324,10 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing global_config_env_test" + $(Q) $(BINDIR)/$(CONFIG)/global_config_env_test || ( echo test global_config_env_test failed ; exit 1 ) + $(E) "[RUN] Testing global_config_test" + $(Q) $(BINDIR)/$(CONFIG)/global_config_test || ( echo test global_config_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" $(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 ) $(E) "[RUN] Testing grpc_alts_credentials_options_test" @@ -3354,6 +3364,7 @@ LIBGPR_SRC = \ src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ + src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ @@ -16390,6 +16401,92 @@ endif endif +GLOBAL_CONFIG_ENV_TEST_SRC = \ + test/core/gprpp/global_config_env_test.cc \ + +GLOBAL_CONFIG_ENV_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GLOBAL_CONFIG_ENV_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/global_config_env_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/global_config_env_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/global_config_env_test: $(PROTOBUF_DEP) $(GLOBAL_CONFIG_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GLOBAL_CONFIG_ENV_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/global_config_env_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/global_config_env_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + +deps_global_config_env_test: $(GLOBAL_CONFIG_ENV_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GLOBAL_CONFIG_ENV_TEST_OBJS:.o=.dep) +endif +endif + + +GLOBAL_CONFIG_TEST_SRC = \ + test/core/gprpp/global_config_test.cc \ + +GLOBAL_CONFIG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GLOBAL_CONFIG_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/global_config_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+. + +$(BINDIR)/$(CONFIG)/global_config_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/global_config_test: $(PROTOBUF_DEP) $(GLOBAL_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GLOBAL_CONFIG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/global_config_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/core/gprpp/global_config_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a + +deps_global_config_test: $(GLOBAL_CONFIG_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GLOBAL_CONFIG_TEST_OBJS:.o=.dep) +endif +endif + + GOLDEN_FILE_TEST_SRC = \ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc \ test/cpp/codegen/golden_file_test.cc \ diff --git a/build.yaml b/build.yaml index 848bf4ba072..f333d982961 100644 --- a/build.yaml +++ b/build.yaml @@ -148,6 +148,7 @@ filegroups: - src/core/lib/gpr/wrap_memcpy.cc - src/core/lib/gprpp/arena.cc - src/core/lib/gprpp/fork.cc + - src/core/lib/gprpp/global_config_env.cc - src/core/lib/gprpp/thd_posix.cc - src/core/lib/gprpp/thd_windows.cc - src/core/lib/profiling/basic_timers.cc @@ -194,6 +195,10 @@ filegroups: - src/core/lib/gprpp/arena.h - src/core/lib/gprpp/atomic.h - src/core/lib/gprpp/fork.h + - src/core/lib/gprpp/global_config.h + - src/core/lib/gprpp/global_config_custom.h + - src/core/lib/gprpp/global_config_env.h + - src/core/lib/gprpp/global_config_generic.h - src/core/lib/gprpp/manual_constructor.h - src/core/lib/gprpp/map.h - src/core/lib/gprpp/memory.h @@ -4722,6 +4727,24 @@ targets: - grpc++ - grpc - gpr +- name: global_config_env_test + build: test + language: c++ + src: + - test/core/gprpp/global_config_env_test.cc + deps: + - gpr + - grpc_test_util_unsecure + uses_polling: false +- name: global_config_test + build: test + language: c++ + src: + - test/core/gprpp/global_config_test.cc + deps: + - gpr + - grpc_test_util_unsecure + uses_polling: false - name: golden_file_test gtest: true build: test diff --git a/config.m4 b/config.m4 index 205d425868e..4616922a38b 100644 --- a/config.m4 +++ b/config.m4 @@ -79,6 +79,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/gpr/wrap_memcpy.cc \ src/core/lib/gprpp/arena.cc \ src/core/lib/gprpp/fork.cc \ + src/core/lib/gprpp/global_config_env.cc \ src/core/lib/gprpp/thd_posix.cc \ src/core/lib/gprpp/thd_windows.cc \ src/core/lib/profiling/basic_timers.cc \ diff --git a/config.w32 b/config.w32 index 3b0fcdd202e..63048c73492 100644 --- a/config.w32 +++ b/config.w32 @@ -54,6 +54,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\gpr\\wrap_memcpy.cc " + "src\\core\\lib\\gprpp\\arena.cc " + "src\\core\\lib\\gprpp\\fork.cc " + + "src\\core\\lib\\gprpp\\global_config_env.cc " + "src\\core\\lib\\gprpp\\thd_posix.cc " + "src\\core\\lib\\gprpp\\thd_windows.cc " + "src\\core\\lib\\profiling\\basic_timers.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3ecdcfe82a4..1809171006f 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -267,6 +267,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -589,6 +593,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index b5ff2c622d0..ec8661b4d19 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -208,6 +208,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', @@ -250,6 +254,7 @@ Pod::Spec.new do |s| 'src/core/lib/gpr/wrap_memcpy.cc', 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', @@ -890,6 +895,10 @@ Pod::Spec.new do |s| 'src/core/lib/gprpp/arena.h', 'src/core/lib/gprpp/atomic.h', 'src/core/lib/gprpp/fork.h', + 'src/core/lib/gprpp/global_config.h', + 'src/core/lib/gprpp/global_config_custom.h', + 'src/core/lib/gprpp/global_config_env.h', + 'src/core/lib/gprpp/global_config_generic.h', 'src/core/lib/gprpp/manual_constructor.h', 'src/core/lib/gprpp/map.h', 'src/core/lib/gprpp/memory.h', diff --git a/grpc.gemspec b/grpc.gemspec index 943e0aaa1a7..59296e8e251 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -102,6 +102,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gprpp/arena.h ) s.files += %w( src/core/lib/gprpp/atomic.h ) s.files += %w( src/core/lib/gprpp/fork.h ) + s.files += %w( src/core/lib/gprpp/global_config.h ) + s.files += %w( src/core/lib/gprpp/global_config_custom.h ) + s.files += %w( src/core/lib/gprpp/global_config_env.h ) + s.files += %w( src/core/lib/gprpp/global_config_generic.h ) s.files += %w( src/core/lib/gprpp/manual_constructor.h ) s.files += %w( src/core/lib/gprpp/map.h ) s.files += %w( src/core/lib/gprpp/memory.h ) @@ -144,6 +148,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/gpr/wrap_memcpy.cc ) s.files += %w( src/core/lib/gprpp/arena.cc ) s.files += %w( src/core/lib/gprpp/fork.cc ) + s.files += %w( src/core/lib/gprpp/global_config_env.cc ) s.files += %w( src/core/lib/gprpp/thd_posix.cc ) s.files += %w( src/core/lib/gprpp/thd_windows.cc ) s.files += %w( src/core/lib/profiling/basic_timers.cc ) diff --git a/grpc.gyp b/grpc.gyp index 5321658508a..14d98d003a6 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -252,6 +252,7 @@ 'src/core/lib/gpr/wrap_memcpy.cc', 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/package.xml b/package.xml index c3e25173349..52b954e20c6 100644 --- a/package.xml +++ b/package.xml @@ -107,6 +107,10 @@ + + + + @@ -149,6 +153,7 @@ + diff --git a/src/core/ext/filters/client_channel/backup_poller.cc b/src/core/ext/filters/client_channel/backup_poller.cc index 3e2faa57bcf..a2d45c04026 100644 --- a/src/core/ext/filters/client_channel/backup_poller.cc +++ b/src/core/ext/filters/client_channel/backup_poller.cc @@ -25,8 +25,8 @@ #include #include #include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/iomgr/timer.h" @@ -56,21 +56,22 @@ static backup_poller* g_poller = nullptr; // guarded by g_poller_mu // treated as const. static int g_poll_interval_ms = DEFAULT_POLL_INTERVAL_MS; +GPR_GLOBAL_CONFIG_DEFINE_INT32(grpc_client_channel_backup_poll_interval_ms, + DEFAULT_POLL_INTERVAL_MS, + "Client channel backup poll interval (ms)"); + static void init_globals() { gpr_mu_init(&g_poller_mu); - char* env = gpr_getenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS"); - if (env != nullptr) { - int poll_interval_ms = gpr_parse_nonnegative_int(env); - if (poll_interval_ms == -1) { - gpr_log(GPR_ERROR, - "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %s, " - "default value %d will be used.", - env, g_poll_interval_ms); - } else { - g_poll_interval_ms = poll_interval_ms; - } + int32_t poll_interval_ms = + GPR_GLOBAL_CONFIG_GET(grpc_client_channel_backup_poll_interval_ms); + if (poll_interval_ms < 0) { + gpr_log(GPR_ERROR, + "Invalid GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS: %d, " + "default value %d will be used.", + poll_interval_ms, g_poll_interval_ms); + } else { + g_poll_interval_ms = poll_interval_ms; } - gpr_free(env); } static void backup_poller_shutdown_unref(backup_poller* p) { diff --git a/src/core/ext/filters/client_channel/backup_poller.h b/src/core/ext/filters/client_channel/backup_poller.h index 8f132f968ce..e1bf4f88b2a 100644 --- a/src/core/ext/filters/client_channel/backup_poller.h +++ b/src/core/ext/filters/client_channel/backup_poller.h @@ -23,6 +23,9 @@ #include #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/gprpp/global_config.h" + +GPR_GLOBAL_CONFIG_DECLARE_INT32(grpc_client_channel_backup_poll_interval_ms); /* Start polling \a interested_parties periodically in the timer thread */ void grpc_client_channel_start_backup_polling( diff --git a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc index 531ea73e9e6..4c929d00ec9 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -20,16 +20,15 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/debug/trace.h" -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/transport/metadata.h" +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_disable_flow_control, false, + "Disable flow control"); + void grpc_chttp2_plugin_init(void) { - g_flow_control_enabled = true; - char* env_variable = gpr_getenv("GRPC_EXPERIMENTAL_DISABLE_FLOW_CONTROL"); - if (env_variable != nullptr) { - g_flow_control_enabled = false; - gpr_free(env_variable); - } + g_flow_control_enabled = + !GPR_GLOBAL_CONFIG_GET(grpc_experimental_disable_flow_control); } void grpc_chttp2_plugin_shutdown(void) {} diff --git a/src/core/lib/gpr/env.h b/src/core/lib/gpr/env.h index aec8a3166b1..5956d17fcfe 100644 --- a/src/core/lib/gpr/env.h +++ b/src/core/lib/gpr/env.h @@ -40,4 +40,7 @@ void gpr_setenv(const char* name, const char* value); level of logging. So DO NOT USE THIS. */ const char* gpr_getenv_silent(const char* name, char** dst); +/* Deletes the variable name from the environment. */ +void gpr_unsetenv(const char* name); + #endif /* GRPC_CORE_LIB_GPR_ENV_H */ diff --git a/src/core/lib/gpr/env_linux.cc b/src/core/lib/gpr/env_linux.cc index fadc42f22f1..e84a9f6064c 100644 --- a/src/core/lib/gpr/env_linux.cc +++ b/src/core/lib/gpr/env_linux.cc @@ -79,4 +79,9 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res == 0); } +void gpr_unsetenv(const char* name) { + int res = unsetenv(name); + GPR_ASSERT(res == 0); +} + #endif /* GPR_LINUX_ENV */ diff --git a/src/core/lib/gpr/env_posix.cc b/src/core/lib/gpr/env_posix.cc index 599f85aa72b..30ddc50f682 100644 --- a/src/core/lib/gpr/env_posix.cc +++ b/src/core/lib/gpr/env_posix.cc @@ -44,4 +44,9 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res == 0); } +void gpr_unsetenv(const char* name) { + int res = unsetenv(name); + GPR_ASSERT(res == 0); +} + #endif /* GPR_POSIX_ENV */ diff --git a/src/core/lib/gpr/env_windows.cc b/src/core/lib/gpr/env_windows.cc index cf8ed60d8f6..72850a9587d 100644 --- a/src/core/lib/gpr/env_windows.cc +++ b/src/core/lib/gpr/env_windows.cc @@ -69,4 +69,11 @@ void gpr_setenv(const char* name, const char* value) { GPR_ASSERT(res); } +void gpr_unsetenv(const char* name) { + LPTSTR tname = gpr_char_to_tchar(name); + BOOL res = SetEnvironmentVariable(tname, NULL); + gpr_free(tname); + GPR_ASSERT(res); +} + #endif /* GPR_WINDOWS_ENV */ diff --git a/src/core/lib/gpr/string.cc b/src/core/lib/gpr/string.cc index 0a76fc1f54a..31d5fdee5be 100644 --- a/src/core/lib/gpr/string.cc +++ b/src/core/lib/gpr/string.cc @@ -332,16 +332,22 @@ void* gpr_memrchr(const void* s, int c, size_t n) { return nullptr; } -bool gpr_is_true(const char* s) { - size_t i; +bool gpr_parse_bool_value(const char* s, bool* dst) { + const char* kTrue[] = {"1", "t", "true", "y", "yes"}; + const char* kFalse[] = {"0", "f", "false", "n", "no"}; + static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal"); + if (s == nullptr) { return false; } - static const char* truthy[] = {"yes", "true", "1"}; - for (i = 0; i < GPR_ARRAY_SIZE(truthy); i++) { - if (0 == gpr_stricmp(s, truthy[i])) { + for (size_t i = 0; i < GPR_ARRAY_SIZE(kTrue); ++i) { + if (gpr_stricmp(s, kTrue[i]) == 0) { + *dst = true; + return true; + } else if (gpr_stricmp(s, kFalse[i]) == 0) { + *dst = false; return true; } } - return false; + return false; // didn't match a legal input } diff --git a/src/core/lib/gpr/string.h b/src/core/lib/gpr/string.h index ce51fe46321..c5efcec3bb1 100644 --- a/src/core/lib/gpr/string.h +++ b/src/core/lib/gpr/string.h @@ -113,7 +113,9 @@ int gpr_stricmp(const char* a, const char* b); void* gpr_memrchr(const void* s, int c, size_t n); -/** Return true if lower(s) equals "true", "yes" or "1", otherwise false. */ -bool gpr_is_true(const char* s); +/* Try to parse given string into a boolean value. + When parsed successfully, dst will have the value and returns true. + Otherwise, it returns false. */ +bool gpr_parse_bool_value(const char* value, bool* dst); #endif /* GRPC_CORE_LIB_GPR_STRING_H */ diff --git a/src/core/lib/gprpp/global_config.h b/src/core/lib/gprpp/global_config.h new file mode 100644 index 00000000000..a1bbf07564c --- /dev/null +++ b/src/core/lib/gprpp/global_config.h @@ -0,0 +1,87 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H + +#include + +#include + +// -------------------------------------------------------------------- +// How to use global configuration variables: +// +// Defining config variables of a specified type: +// GPR_GLOBAL_CONFIG_DEFINE_*TYPE*(name, default_value, help); +// +// Supported TYPEs: BOOL, INT32, STRING +// +// It's recommended to use lowercase letters for 'name' like +// regular variables. The builtin configuration system uses +// environment variable and the name is converted to uppercase +// when looking up the value. For example, +// GPR_GLOBAL_CONFIG_DEFINE(grpc_latency) looks up the value with the +// name, "GRPC_LATENCY". +// +// The variable initially has the specified 'default_value' +// which must be an expression convertible to 'Type'. +// 'default_value' may be evaluated 0 or more times, +// and at an unspecified time; keep it +// simple and usually free of side-effects. +// +// GPR_GLOBAL_CONFIG_DEFINE_*TYPE* should not be called in a C++ header. +// It should be called at the top-level (outside any namespaces) +// in a .cc file. +// +// Getting the variables: +// GPR_GLOBAL_CONFIG_GET(name) +// +// If error happens during getting variables, error messages will +// be logged and default value will be returned. +// +// Setting the variables with new value: +// GPR_GLOBAL_CONFIG_SET(name, new_value) +// +// Declaring config variables for other modules to access: +// GPR_GLOBAL_CONFIG_DECLARE_*TYPE*(name) + +// -------------------------------------------------------------------- +// How to customize the global configuration system: +// +// How to read and write configuration value can be customized. +// Builtin system uses environment variables but it can be extended to +// support command-line flag, file, etc. +// +// To customize it, following macros should be redefined. +// +// GPR_GLOBAL_CONFIG_DEFINE_BOOL +// GPR_GLOBAL_CONFIG_DEFINE_INT32 +// GPR_GLOBAL_CONFIG_DEFINE_STRING +// +// These macros should define functions for getting and setting variable. +// For example, GPR_GLOBAL_CONFIG_DEFINE_BOOL(test, ...) would define two +// functions. +// +// bool gpr_global_config_get_test(); +// void gpr_global_config_set_test(bool value); + +#include "src/core/lib/gprpp/global_config_env.h" + +#include "src/core/lib/gprpp/global_config_custom.h" + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_H */ diff --git a/src/core/lib/gprpp/global_config_custom.h b/src/core/lib/gprpp/global_config_custom.h new file mode 100644 index 00000000000..dd011fb34bf --- /dev/null +++ b/src/core/lib/gprpp/global_config_custom.h @@ -0,0 +1,29 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H + +// This is a placeholder for custom global configuration implementaion. +// To use the custom one, please define following macros here. +// +// GPR_GLOBAL_CONFIG_DEFINE_BOOL +// GPR_GLOBAL_CONFIG_DEFINE_INT32 +// GPR_GLOBAL_CONFIG_DEFINE_STRING + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_CUSTOM_H */ diff --git a/src/core/lib/gprpp/global_config_env.cc b/src/core/lib/gprpp/global_config_env.cc new file mode 100644 index 00000000000..fb14805d01b --- /dev/null +++ b/src/core/lib/gprpp/global_config_env.cc @@ -0,0 +1,135 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/lib/gprpp/global_config_env.h" + +#include +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" + +#include +#include + +namespace grpc_core { + +namespace { + +void DefaultGlobalConfigEnvErrorFunction(const char* error_message) { + gpr_log(GPR_ERROR, "%s", error_message); +} + +GlobalConfigEnvErrorFunctionType g_global_config_env_error_func = + DefaultGlobalConfigEnvErrorFunction; + +void LogParsingError(const char* name, const char* value) { + char* error_message; + gpr_asprintf(&error_message, + "Illegal value '%s' specified for environment variable '%s'", + value, name); + (*g_global_config_env_error_func)(error_message); + gpr_free(error_message); +} + +} // namespace + +void SetGlobalConfigEnvErrorFunction(GlobalConfigEnvErrorFunctionType func) { + g_global_config_env_error_func = func; +} + +UniquePtr GlobalConfigEnv::GetValue() { + return UniquePtr(gpr_getenv(GetName())); +} + +void GlobalConfigEnv::SetValue(const char* value) { + gpr_setenv(GetName(), value); +} + +void GlobalConfigEnv::Unset() { gpr_unsetenv(GetName()); } + +char* GlobalConfigEnv::GetName() { + // This makes sure that name_ is in a canonical form having uppercase + // letters. This is okay to be called serveral times. + for (char* c = name_; *c != 0; ++c) { + *c = toupper(*c); + } + return name_; +} +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvBool needs to be trivially destructible."); + +bool GlobalConfigEnvBool::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return default_value_; + } + // parsing given value string. + bool result = false; + if (!gpr_parse_bool_value(str.get(), &result)) { + LogParsingError(GetName(), str.get()); + result = default_value_; + } + return result; +} + +void GlobalConfigEnvBool::Set(bool value) { + SetValue(value ? "true" : "false"); +} + +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvInt32 needs to be trivially destructible."); + +int32_t GlobalConfigEnvInt32::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return default_value_; + } + // parsing given value string. + char* end = str.get(); + long result = strtol(str.get(), &end, 10); + if (*end != 0) { + LogParsingError(GetName(), str.get()); + result = default_value_; + } + return static_cast(result); +} + +void GlobalConfigEnvInt32::Set(int32_t value) { + char buffer[GPR_LTOA_MIN_BUFSIZE]; + gpr_ltoa(value, buffer); + SetValue(buffer); +} + +static_assert(std::is_trivially_destructible::value, + "GlobalConfigEnvString needs to be trivially destructible."); + +UniquePtr GlobalConfigEnvString::Get() { + UniquePtr str = GetValue(); + if (str == nullptr) { + return UniquePtr(gpr_strdup(default_value_)); + } + return str; +} + +void GlobalConfigEnvString::Set(const char* value) { SetValue(value); } + +} // namespace grpc_core diff --git a/src/core/lib/gprpp/global_config_env.h b/src/core/lib/gprpp/global_config_env.h new file mode 100644 index 00000000000..3d3038895d3 --- /dev/null +++ b/src/core/lib/gprpp/global_config_env.h @@ -0,0 +1,131 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H + +#include + +#include "src/core/lib/gprpp/global_config_generic.h" +#include "src/core/lib/gprpp/memory.h" + +namespace grpc_core { + +typedef void (*GlobalConfigEnvErrorFunctionType)(const char* error_message); + +/* + * Set global_config_env_error_function which is called when config system + * encounters errors such as parsing error. What the default function does + * is logging error message. + */ +void SetGlobalConfigEnvErrorFunction(GlobalConfigEnvErrorFunctionType func); + +// Base class for all classes to access environment variables. +class GlobalConfigEnv { + protected: + // `name` should be writable and alive after constructor is called. + constexpr explicit GlobalConfigEnv(char* name) : name_(name) {} + + public: + // Returns the value of `name` variable. + UniquePtr GetValue(); + + // Sets the value of `name` variable. + void SetValue(const char* value); + + // Unsets `name` variable. + void Unset(); + + protected: + char* GetName(); + + private: + char* name_; +}; + +class GlobalConfigEnvBool : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvBool(char* name, bool default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + bool Get(); + void Set(bool value); + + private: + bool default_value_; +}; + +class GlobalConfigEnvInt32 : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvInt32(char* name, int32_t default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + int32_t Get(); + void Set(int32_t value); + + private: + int32_t default_value_; +}; + +class GlobalConfigEnvString : public GlobalConfigEnv { + public: + constexpr GlobalConfigEnvString(char* name, const char* default_value) + : GlobalConfigEnv(name), default_value_(default_value) {} + + UniquePtr Get(); + void Set(const char* value); + + private: + const char* default_value_; +}; + +} // namespace grpc_core + +// Macros for defining global config instances using environment variables. +// This defines a GlobalConfig*Type* instance with arguments for +// mutable variable name and default value. +// Mutable name (g_env_str_##name) is here for having an array +// for the canonical name without dynamic allocation. +// `help` argument is ignored for this implementation. + +#define GPR_GLOBAL_CONFIG_DEFINE_BOOL(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvBool g_env_##name(g_env_str_##name, \ + default_value); \ + bool gpr_global_config_get_##name() { return g_env_##name.Get(); } \ + void gpr_global_config_set_##name(bool value) { g_env_##name.Set(value); } + +#define GPR_GLOBAL_CONFIG_DEFINE_INT32(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvInt32 g_env_##name(g_env_str_##name, \ + default_value); \ + int32_t gpr_global_config_get_##name() { return g_env_##name.Get(); } \ + void gpr_global_config_set_##name(int32_t value) { g_env_##name.Set(value); } + +#define GPR_GLOBAL_CONFIG_DEFINE_STRING(name, default_value, help) \ + static char g_env_str_##name[] = #name; \ + static ::grpc_core::GlobalConfigEnvString g_env_##name(g_env_str_##name, \ + default_value); \ + ::grpc_core::UniquePtr gpr_global_config_get_##name() { \ + return g_env_##name.Get(); \ + } \ + void gpr_global_config_set_##name(const char* value) { \ + g_env_##name.Set(value); \ + } + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_ENV_H */ diff --git a/src/core/lib/gprpp/global_config_generic.h b/src/core/lib/gprpp/global_config_generic.h new file mode 100644 index 00000000000..d3e3e2a2dbe --- /dev/null +++ b/src/core/lib/gprpp/global_config_generic.h @@ -0,0 +1,44 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H +#define GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H + +#include + +#include "src/core/lib/gprpp/memory.h" + +#include + +#define GPR_GLOBAL_CONFIG_GET(name) gpr_global_config_get_##name() + +#define GPR_GLOBAL_CONFIG_SET(name, value) gpr_global_config_set_##name(value) + +#define GPR_GLOBAL_CONFIG_DECLARE_BOOL(name) \ + extern bool gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(bool value) + +#define GPR_GLOBAL_CONFIG_DECLARE_INT32(name) \ + extern int32_t gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(int32_t value) + +#define GPR_GLOBAL_CONFIG_DECLARE_STRING(name) \ + extern grpc_core::UniquePtr gpr_global_config_get_##name(); \ + extern void gpr_global_config_set_##name(const char* value) + +#endif /* GRPC_CORE_LIB_GPRPP_GLOBAL_CONFIG_GENERIC_H */ diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc index 0fbfcfce04f..fd011788a06 100644 --- a/src/core/lib/iomgr/iomgr.cc +++ b/src/core/lib/iomgr/iomgr.cc @@ -29,9 +29,9 @@ #include #include -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/thd.h" #include "src/core/lib/iomgr/buffer_list.h" #include "src/core/lib/iomgr/exec_ctx.h" @@ -41,6 +41,9 @@ #include "src/core/lib/iomgr/timer.h" #include "src/core/lib/iomgr/timer_manager.h" +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_abort_on_leaks, false, + "Abort when leak is found"); + static gpr_mu g_mu; static gpr_cv g_rcv; static int g_shutdown; @@ -186,8 +189,5 @@ void grpc_iomgr_unregister_object(grpc_iomgr_object* obj) { } bool grpc_iomgr_abort_on_leaks(void) { - char* env = gpr_getenv("GRPC_ABORT_ON_LEAKS"); - bool should_we = gpr_is_true(env); - gpr_free(env); - return should_we; + return GPR_GLOBAL_CONFIG_GET(grpc_abort_on_leaks); } diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc index c9af5ca6ad0..1eefff6fe24 100644 --- a/src/core/lib/security/security_connector/ssl_utils.cc +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -30,6 +30,7 @@ #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/host_port.h" #include "src/core/lib/gpr/string.h" +#include "src/core/lib/gprpp/global_config.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" @@ -47,9 +48,8 @@ static const char* installed_roots_path = /** Environment variable used as a flag to enable/disable loading system root certificates from the OS trust store. */ -#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" -#endif +GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_not_use_system_ssl_roots, false, + "Disable loading system root certificates."); #ifndef TSI_OPENSSL_ALPN_SUPPORT #define TSI_OPENSSL_ALPN_SUPPORT 1 @@ -428,10 +428,8 @@ const char* DefaultSslRootStore::GetPemRootCerts() { grpc_slice DefaultSslRootStore::ComputePemRootCerts() { grpc_slice result = grpc_empty_slice(); - char* not_use_system_roots_env_value = - gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); - const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); - gpr_free(not_use_system_roots_env_value); + const bool not_use_system_roots = + GPR_GLOBAL_CONFIG_GET(grpc_not_use_system_ssl_roots); // First try to load the roots from the environment. char* default_root_certs_path = gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 2e358f9c1ef..615bf4ee0dc 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -53,6 +53,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/gpr/wrap_memcpy.cc', 'src/core/lib/gprpp/arena.cc', 'src/core/lib/gprpp/fork.cc', + 'src/core/lib/gprpp/global_config_env.cc', 'src/core/lib/gprpp/thd_posix.cc', 'src/core/lib/gprpp/thd_windows.cc', 'src/core/lib/profiling/basic_timers.cc', diff --git a/test/core/gpr/env_test.cc b/test/core/gpr/env_test.cc index a8206bd3cfd..3883a5df997 100644 --- a/test/core/gpr/env_test.cc +++ b/test/core/gpr/env_test.cc @@ -42,8 +42,22 @@ static void test_setenv_getenv(void) { gpr_free(retrieved_value); } +static void test_unsetenv(void) { + const char* name = "FOO"; + const char* value = "BAR"; + char* retrieved_value; + + LOG_TEST_NAME("test_unsetenv"); + + gpr_setenv(name, value); + gpr_unsetenv(name); + retrieved_value = gpr_getenv(name); + GPR_ASSERT(retrieved_value == nullptr); +} + int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); test_setenv_getenv(); + test_unsetenv(); return 0; } diff --git a/test/core/gpr/string_test.cc b/test/core/gpr/string_test.cc index 7da7b18778b..5e3ed9d5dfd 100644 --- a/test/core/gpr/string_test.cc +++ b/test/core/gpr/string_test.cc @@ -279,19 +279,20 @@ static void test_memrchr(void) { GPR_ASSERT(0 == strcmp((const char*)gpr_memrchr("hello", 'l', 5), "lo")); } -static void test_is_true(void) { - LOG_TEST_NAME("test_is_true"); - - GPR_ASSERT(true == gpr_is_true("True")); - GPR_ASSERT(true == gpr_is_true("true")); - GPR_ASSERT(true == gpr_is_true("TRUE")); - GPR_ASSERT(true == gpr_is_true("Yes")); - GPR_ASSERT(true == gpr_is_true("yes")); - GPR_ASSERT(true == gpr_is_true("YES")); - GPR_ASSERT(true == gpr_is_true("1")); - GPR_ASSERT(false == gpr_is_true(nullptr)); - GPR_ASSERT(false == gpr_is_true("")); - GPR_ASSERT(false == gpr_is_true("0")); +static void test_parse_bool_value(void) { + LOG_TEST_NAME("test_parse_bool_value"); + + bool ret; + GPR_ASSERT(true == gpr_parse_bool_value("truE", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("falsE", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("1", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("0", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("Yes", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("No", &ret) && false == ret); + GPR_ASSERT(true == gpr_parse_bool_value("Y", &ret) && true == ret); + GPR_ASSERT(true == gpr_parse_bool_value("N", &ret) && false == ret); + GPR_ASSERT(false == gpr_parse_bool_value(nullptr, &ret)); + GPR_ASSERT(false == gpr_parse_bool_value("", &ret)); } int main(int argc, char** argv) { @@ -307,6 +308,6 @@ int main(int argc, char** argv) { test_leftpad(); test_stricmp(); test_memrchr(); - test_is_true(); + test_parse_bool_value(); return 0; } diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index 4665827e10f..cd3232addfd 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -28,6 +28,32 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "global_config_test", + srcs = ["global_config_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "global_config_env_test", + srcs = ["global_config_env_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:grpc_test_util", + ], +) + grpc_cc_test( name = "manual_constructor_test", srcs = ["manual_constructor_test.cc"], diff --git a/test/core/gprpp/global_config_env_test.cc b/test/core/gprpp/global_config_env_test.cc new file mode 100644 index 00000000000..74905d3b07c --- /dev/null +++ b/test/core/gprpp/global_config_env_test.cc @@ -0,0 +1,130 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include + +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config_env.h" +#include "src/core/lib/gprpp/memory.h" + +namespace { + +bool g_config_error_function_called; + +void ClearConfigErrorCalled() { g_config_error_function_called = false; } + +bool IsConfigErrorCalled() { return g_config_error_function_called; } + +// This function is for preventing the program from invoking +// an error handler due to configuration error and +// make test routines know whether there is error. +void FakeConfigErrorFunction(const char* error_message) { + g_config_error_function_called = true; +} + +class GlobalConfigEnvTest : public ::testing::Test { + protected: + void SetUp() override { ClearConfigErrorCalled(); } + void TearDown() override { EXPECT_FALSE(IsConfigErrorCalled()); } +}; + +} // namespace + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(bool_var, true, ""); +GPR_GLOBAL_CONFIG_DEFINE_INT32(int32_var, 1234, ""); +GPR_GLOBAL_CONFIG_DEFINE_STRING(string_var, "Apple", ""); + +TEST_F(GlobalConfigEnvTest, BoolWithEnvTest) { + const char* bool_var_name = "BOOL_VAR"; + + gpr_unsetenv(bool_var_name); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + gpr_setenv(bool_var_name, "true"); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + gpr_setenv(bool_var_name, "false"); + EXPECT_FALSE(GPR_GLOBAL_CONFIG_GET(bool_var)); + + EXPECT_FALSE(IsConfigErrorCalled()); + + gpr_setenv(bool_var_name, ""); + GPR_GLOBAL_CONFIG_GET(bool_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); + + gpr_setenv(bool_var_name, "!"); + GPR_GLOBAL_CONFIG_GET(bool_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); +} + +TEST_F(GlobalConfigEnvTest, Int32WithEnvTest) { + const char* int32_var_name = "INT32_VAR"; + + gpr_unsetenv(int32_var_name); + EXPECT_EQ(1234, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "0"); + EXPECT_EQ(0, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "-123456789"); + EXPECT_EQ(-123456789, GPR_GLOBAL_CONFIG_GET(int32_var)); + + gpr_setenv(int32_var_name, "123456789"); + EXPECT_EQ(123456789, GPR_GLOBAL_CONFIG_GET(int32_var)); + + EXPECT_FALSE(IsConfigErrorCalled()); + + gpr_setenv(int32_var_name, "-1AB"); + GPR_GLOBAL_CONFIG_GET(int32_var); + EXPECT_TRUE(IsConfigErrorCalled()); + ClearConfigErrorCalled(); +} + +TEST_F(GlobalConfigEnvTest, StringWithEnvTest) { + const char* string_var_name = "STRING_VAR"; + grpc_core::UniquePtr value; + + gpr_unsetenv(string_var_name); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Apple")); + + gpr_setenv(string_var_name, "Banana"); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Banana")); + + gpr_setenv(string_var_name, ""); + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "")); +} + +int main(int argc, char** argv) { + // Not to abort the test when parsing error happens. + grpc_core::SetGlobalConfigEnvErrorFunction(&FakeConfigErrorFunction); + + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/core/gprpp/global_config_test.cc b/test/core/gprpp/global_config_test.cc new file mode 100644 index 00000000000..7da78b690b1 --- /dev/null +++ b/test/core/gprpp/global_config_test.cc @@ -0,0 +1,65 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include + +#include +#include + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gprpp/global_config.h" +#include "src/core/lib/gprpp/memory.h" + +GPR_GLOBAL_CONFIG_DECLARE_BOOL(bool_var); + +GPR_GLOBAL_CONFIG_DEFINE_BOOL(bool_var, false, ""); +GPR_GLOBAL_CONFIG_DEFINE_INT32(int32_var, 0, ""); +GPR_GLOBAL_CONFIG_DEFINE_STRING(string_var, "", ""); + +TEST(GlobalConfigTest, BoolTest) { + EXPECT_FALSE(GPR_GLOBAL_CONFIG_GET(bool_var)); + GPR_GLOBAL_CONFIG_SET(bool_var, true); + EXPECT_TRUE(GPR_GLOBAL_CONFIG_GET(bool_var)); +} + +TEST(GlobalConfigTest, Int32Test) { + EXPECT_EQ(0, GPR_GLOBAL_CONFIG_GET(int32_var)); + GPR_GLOBAL_CONFIG_SET(int32_var, 1024); + EXPECT_EQ(1024, GPR_GLOBAL_CONFIG_GET(int32_var)); +} + +TEST(GlobalConfigTest, StringTest) { + grpc_core::UniquePtr value; + + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "")); + + GPR_GLOBAL_CONFIG_SET(string_var, "Test"); + + value = GPR_GLOBAL_CONFIG_GET(string_var); + EXPECT_EQ(0, strcmp(value.get(), "Test")); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index e09f54dcc3f..840d668e0d8 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -32,6 +32,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/gpr/tls.h" #include "src/core/lib/iomgr/port.h" @@ -1883,7 +1884,7 @@ INSTANTIATE_TEST_CASE_P(AsyncEnd2endServerTryCancel, int main(int argc, char** argv) { // Change the backup poll interval from 5s to 100ms to speed up the // ReconnectChannel test - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "100"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 100); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); int ret = RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index 6623a2ff55f..ca20ebbaeee 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -37,13 +37,13 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/tcp_client.h" @@ -142,7 +142,7 @@ class ClientLbEnd2endTest : public ::testing::Test { grpc_fake_transport_security_credentials_create())) { // Make the backup poller poll very frequently in order to pick up // updates from all the subchannels's FDs. - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index fb951fd44e6..a2b9ebe7197 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -34,6 +34,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/iomgr.h" #include "src/core/lib/security/credentials/credentials.h" @@ -2104,7 +2105,7 @@ INSTANTIATE_TEST_CASE_P( } // namespace grpc int main(int argc, char** argv) { - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 200); grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index bd915b04eee..f93e2548c8e 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -34,11 +34,11 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/service_config.h" -#include "src/core/lib/gpr/env.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" @@ -375,7 +375,7 @@ class GrpclbEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds) { // Make the backup poller poll very frequently in order to pick up // updates from all the subchannels's FDs. - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 2952c194d48..d6f2685642c 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -33,6 +33,7 @@ #include #include +#include "src/core/ext/filters/client_channel/backup_poller.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -370,7 +371,7 @@ class XdsEnd2endTest : public ::testing::Test { client_load_reporting_interval_seconds) { // Make the backup poller poll very frequently in order to pick up // updates from all the subchannels's FDs. - gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1"); + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); } void SetUp() override { diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index 2e54993a31c..4d1beb7ec37 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -146,8 +146,9 @@ vector ParseExpectedAddrs(std::string expected_addrs) { expected_addrs = expected_addrs.substr(next_comma + 1, std::string::npos); // get the next is_balancer 'bool' associated with this address size_t next_semicolon = expected_addrs.find(';'); - bool is_balancer = - gpr_is_true(expected_addrs.substr(0, next_semicolon).c_str()); + bool is_balancer = false; + gpr_parse_bool_value(expected_addrs.substr(0, next_semicolon).c_str(), + &is_balancer); out.emplace_back(GrpcLBAddress(next_addr, is_balancer)); if (next_semicolon == std::string::npos) { break; diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 357efa0d684..bc2a32d3cfd 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1086,6 +1086,10 @@ src/core/lib/gprpp/arena.h \ src/core/lib/gprpp/atomic.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/fork.h \ +src/core/lib/gprpp/global_config.h \ +src/core/lib/gprpp/global_config_custom.h \ +src/core/lib/gprpp/global_config_env.h \ +src/core/lib/gprpp/global_config_generic.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 3a9951b0364..870d6348df0 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1165,6 +1165,11 @@ src/core/lib/gprpp/atomic.h \ src/core/lib/gprpp/debug_location.h \ src/core/lib/gprpp/fork.cc \ src/core/lib/gprpp/fork.h \ +src/core/lib/gprpp/global_config.h \ +src/core/lib/gprpp/global_config_custom.h \ +src/core/lib/gprpp/global_config_env.cc \ +src/core/lib/gprpp/global_config_env.h \ +src/core/lib/gprpp/global_config_generic.h \ src/core/lib/gprpp/inlined_vector.h \ src/core/lib/gprpp/manual_constructor.h \ src/core/lib/gprpp/map.h \ diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 9778343cd94..e07bb48675a 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -3662,6 +3662,36 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "grpc_test_util_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "global_config_env_test", + "src": [ + "test/core/gprpp/global_config_env_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "grpc_test_util_unsecure" + ], + "headers": [], + "is_filegroup": false, + "language": "c++", + "name": "global_config_test", + "src": [ + "test/core/gprpp/global_config_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -8019,6 +8049,7 @@ "src/core/lib/gpr/wrap_memcpy.cc", "src/core/lib/gprpp/arena.cc", "src/core/lib/gprpp/fork.cc", + "src/core/lib/gprpp/global_config_env.cc", "src/core/lib/gprpp/thd_posix.cc", "src/core/lib/gprpp/thd_windows.cc", "src/core/lib/profiling/basic_timers.cc", @@ -8069,6 +8100,10 @@ "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", @@ -8118,6 +8153,10 @@ "src/core/lib/gprpp/arena.h", "src/core/lib/gprpp/atomic.h", "src/core/lib/gprpp/fork.h", + "src/core/lib/gprpp/global_config.h", + "src/core/lib/gprpp/global_config_custom.h", + "src/core/lib/gprpp/global_config_env.h", + "src/core/lib/gprpp/global_config_generic.h", "src/core/lib/gprpp/manual_constructor.h", "src/core/lib/gprpp/map.h", "src/core/lib/gprpp/memory.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index ec2e570bea7..8c14282acbb 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -4499,6 +4499,54 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "global_config_env_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "global_config_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [ "--generated_file_path=gens/src/proto/grpc/testing/" From b3fb277da6468de843e41bd6434b6b6d4ec46dc3 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Wed, 1 May 2019 13:52:58 -0400 Subject: [PATCH 110/112] Reset slices pointer to base_slices when slice_bufer length is 0. Currently, we keep increasing the slice pointer, and can run out of the inline space or try to realloc the non-inline space unncessarily. Simply set slices back to the start of the base_slices, when we know the length of the slice_buffer is 0. Note: This will change the behavior of undo_take_first(), if user tries to grow the slie_buffer, between take_first() and undo_take_first() calls. That said, it's not legal to add something to the buffer in between take_first() and undo_take_first(). So, we shouldn't have any issue. --- src/core/lib/slice/slice_buffer.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/lib/slice/slice_buffer.cc b/src/core/lib/slice/slice_buffer.cc index 1f1c08b1594..ce3b5512d1d 100644 --- a/src/core/lib/slice/slice_buffer.cc +++ b/src/core/lib/slice/slice_buffer.cc @@ -33,6 +33,10 @@ #define GROW(x) (3 * (x) / 2) static void maybe_embiggen(grpc_slice_buffer* sb) { + if (sb->length == 0) { + sb->slices = sb->base_slices; + } + /* How far away from sb->base_slices is sb->slices pointer */ size_t slice_offset = static_cast(sb->slices - sb->base_slices); size_t slice_count = sb->count + slice_offset; @@ -177,6 +181,7 @@ void grpc_slice_buffer_reset_and_unref_internal(grpc_slice_buffer* sb) { sb->count = 0; sb->length = 0; + sb->slices = sb->base_slices; } void grpc_slice_buffer_reset_and_unref(grpc_slice_buffer* sb) { From 926bbe3a2e3f94eec591fbf19795a28f598806c1 Mon Sep 17 00:00:00 2001 From: Soheil Hassas Yeganeh Date: Tue, 30 Apr 2019 18:47:16 -0400 Subject: [PATCH 111/112] Add a fast path in grpc_error_get_status() for GRPC_ERROR_NONE. In most of the cases, as we hope, RPCs shouldn't have errors. But, in grpc_error_get_status() we treat GRPC_ERROR_NONE similar to other errors, and waste quite a few cycles. This patch is part of a larger performance improvements. On client side, this particular code path accounts for 0.5%+. --- src/core/lib/transport/error_utils.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 558f1d494cd..eb4e8c3a282 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -48,6 +48,18 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline, grpc_status_code* code, grpc_slice* slice, grpc_http2_error_code* http_error, const char** error_string) { + // Fast path: We expect no error. + if (GPR_LIKELY(error == GRPC_ERROR_NONE)) { + if (code != nullptr) *code = GRPC_STATUS_OK; + if (slice != nullptr) { + grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, slice); + } + if (http_error != nullptr) { + *http_error = GRPC_HTTP2_NO_ERROR; + } + return; + } + // Start with the parent error and recurse through the tree of children // until we find the first one that has a status code. grpc_error* found_error = From e18ed03c043d237b81bc32ddbd7d79593e2f7f19 Mon Sep 17 00:00:00 2001 From: Esun Kim Date: Thu, 2 May 2019 16:58:37 -0700 Subject: [PATCH 112/112] Made gRPC inialized after entering main function in microbenchmarks. --- test/cpp/microbenchmarks/bm_alarm.cc | 3 +-- test/cpp/microbenchmarks/bm_byte_buffer.cc | 4 +--- test/cpp/microbenchmarks/bm_call_create.cc | 3 +-- test/cpp/microbenchmarks/bm_channel.cc | 3 +-- test/cpp/microbenchmarks/bm_chttp2_hpack.cc | 3 +-- test/cpp/microbenchmarks/bm_chttp2_transport.cc | 6 +++--- test/cpp/microbenchmarks/bm_closure.cc | 3 +-- test/cpp/microbenchmarks/bm_cq.cc | 3 +-- test/cpp/microbenchmarks/bm_error.cc | 3 +-- .../bm_fullstack_streaming_ping_pong.cc | 4 +--- .../bm_fullstack_streaming_pump.cc | 4 +--- .../cpp/microbenchmarks/bm_fullstack_trickle.cc | 8 +++----- .../bm_fullstack_unary_ping_pong.cc | 4 +--- test/cpp/microbenchmarks/bm_metadata.cc | 3 +-- test/cpp/microbenchmarks/bm_pollset.cc | 3 +-- test/cpp/microbenchmarks/bm_timer.cc | 3 +-- test/cpp/microbenchmarks/fullstack_fixtures.h | 4 ++-- test/cpp/microbenchmarks/helpers.cc | 17 ++++++++++++++++- test/cpp/microbenchmarks/helpers.h | 14 +++++--------- 19 files changed, 43 insertions(+), 52 deletions(-) diff --git a/test/cpp/microbenchmarks/bm_alarm.cc b/test/cpp/microbenchmarks/bm_alarm.cc index 64aad6476de..d95771a57c6 100644 --- a/test/cpp/microbenchmarks/bm_alarm.cc +++ b/test/cpp/microbenchmarks/bm_alarm.cc @@ -30,8 +30,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_Alarm_Tag_Immediate(benchmark::State& state) { TrackCounters track_counters; CompletionQueue cq; @@ -57,6 +55,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc index 644c27c4873..595cc734b69 100644 --- a/test/cpp/microbenchmarks/bm_byte_buffer.cc +++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc @@ -30,7 +30,6 @@ namespace grpc { namespace testing { static void BM_ByteBuffer_Copy(benchmark::State& state) { - Library::get(); int num_slices = state.range(0); size_t slice_size = state.range(1); std::vector slices; @@ -48,7 +47,6 @@ static void BM_ByteBuffer_Copy(benchmark::State& state) { BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}}); static void BM_ByteBufferReader_Next(benchmark::State& state) { - Library::get(); const int num_slices = state.range(0); constexpr size_t kSliceSize = 16; std::vector slices; @@ -82,7 +80,6 @@ static void BM_ByteBufferReader_Next(benchmark::State& state) { BENCHMARK(BM_ByteBufferReader_Next)->Ranges({{64 * 1024, 1024 * 1024}}); static void BM_ByteBufferReader_Peek(benchmark::State& state) { - Library::get(); const int num_slices = state.range(0); constexpr size_t kSliceSize = 16; std::vector slices; @@ -125,6 +122,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 53087a551b5..3bd1464b2aa 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -47,8 +47,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - void BM_Zalloc(benchmark::State& state) { // speed of light for call creation is zalloc, so benchmark a few interesting // sizes @@ -823,6 +821,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_channel.cc b/test/cpp/microbenchmarks/bm_channel.cc index 15ac9975400..88856c3439b 100644 --- a/test/cpp/microbenchmarks/bm_channel.cc +++ b/test/cpp/microbenchmarks/bm_channel.cc @@ -23,8 +23,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - class ChannelDestroyerFixture { public: ChannelDestroyerFixture() {} @@ -83,6 +81,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc index 0521166db95..d0ed1da7671 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc @@ -36,8 +36,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static grpc_slice MakeSlice(std::vector bytes) { grpc_slice s = grpc_slice_malloc(bytes.size()); uint8_t* p = GRPC_SLICE_START_PTR(s); @@ -928,6 +926,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc index dc10fcb89d3..05504584c20 100644 --- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc +++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc @@ -36,8 +36,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - //////////////////////////////////////////////////////////////////////////////// // Helper classes // @@ -57,7 +55,8 @@ class DummyEndpoint : public grpc_endpoint { get_fd, can_track_err}; grpc_endpoint::vtable = &my_vtable; - ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint"); + ru_ = grpc_resource_user_create(LibraryInitializer::get().rq(), + "dummy_endpoint"); } void PushInput(grpc_slice slice) { @@ -642,6 +641,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc index e1f1e92d4d8..84b1c536bf0 100644 --- a/test/cpp/microbenchmarks/bm_closure.cc +++ b/test/cpp/microbenchmarks/bm_closure.cc @@ -30,8 +30,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static void BM_NoOpExecCtx(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -425,6 +423,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc index a7cb939265f..263314deb93 100644 --- a/test/cpp/microbenchmarks/bm_cq.cc +++ b/test/cpp/microbenchmarks/bm_cq.cc @@ -32,8 +32,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - static void BM_CreateDestroyCpp(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -156,6 +154,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index ae557a580aa..a71817f7e54 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -27,8 +27,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - class ErrorDeleter { public: void operator()(grpc_error* error) { GRPC_ERROR_UNREF(error); } @@ -318,6 +316,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc index 34df77aca3c..60ca9a093ed 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc @@ -24,9 +24,6 @@ namespace grpc { namespace testing { -// force library initialization -auto& force_library_initialization = Library::get(); - /******************************************************************************* * CONFIGURATIONS */ @@ -122,6 +119,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc index da98f3cbcd4..d4533e6c78e 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc @@ -28,9 +28,6 @@ namespace testing { * CONFIGURATIONS */ -// force library initialization -auto& force_library_initialization = Library::get(); - BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, TCP) ->Range(0, 128 * 1024 * 1024); BENCHMARK_TEMPLATE(BM_PumpStreamClientToServer, UDS) @@ -72,6 +69,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc index 1af92d2c80c..2d733bcaa42 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc @@ -214,8 +214,8 @@ class TrickledCHTTP2 : public EndpointPairFixture { static grpc_endpoint_pair MakeEndpoints(size_t kilobits, grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - stats); + grpc_passthru_endpoint_create(&p.client, &p.server, + LibraryInitializer::get().rq(), stats); double bytes_per_second = 125.0 * kilobits; p.client = grpc_trickle_endpoint_create(p.client, bytes_per_second); p.server = grpc_trickle_endpoint_create(p.server, bytes_per_second); @@ -235,9 +235,6 @@ class TrickledCHTTP2 : public EndpointPairFixture { } }; -// force library initialization -auto& force_library_initialization = Library::get(); - static void TrickleCQNext(TrickledCHTTP2* fixture, void** t, bool* ok, int64_t iteration) { while (true) { @@ -465,6 +462,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); grpc_timer_manager_set_threading(false); diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc index d4bd58b9838..3e8f9344021 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc @@ -24,9 +24,6 @@ namespace grpc { namespace testing { -// force library initialization -auto& force_library_initialization = Library::get(); - /******************************************************************************* * CONFIGURATIONS */ @@ -174,6 +171,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc index 553b33c4028..ff8fe541dfc 100644 --- a/test/cpp/microbenchmarks/bm_metadata.cc +++ b/test/cpp/microbenchmarks/bm_metadata.cc @@ -27,8 +27,6 @@ #include "test/cpp/microbenchmarks/helpers.h" #include "test/cpp/util/test_config.h" -auto& force_library_initialization = Library::get(); - static void BM_SliceFromStatic(benchmark::State& state) { TrackCounters track_counters; while (state.KeepRunning()) { @@ -298,6 +296,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc index 050c7f7c171..f8e36f178e4 100644 --- a/test/cpp/microbenchmarks/bm_pollset.cc +++ b/test/cpp/microbenchmarks/bm_pollset.cc @@ -40,8 +40,6 @@ #include #endif -auto& force_library_initialization = Library::get(); - static void shutdown_ps(void* ps, grpc_error* error) { grpc_pollset_destroy(static_cast(ps)); } @@ -264,6 +262,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/bm_timer.cc b/test/cpp/microbenchmarks/bm_timer.cc index f5a411251b5..53aaead992d 100644 --- a/test/cpp/microbenchmarks/bm_timer.cc +++ b/test/cpp/microbenchmarks/bm_timer.cc @@ -32,8 +32,6 @@ namespace grpc { namespace testing { -auto& force_library_initialization = Library::get(); - struct TimerClosure { grpc_timer timer; grpc_closure closure; @@ -111,6 +109,7 @@ void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } } // namespace benchmark int main(int argc, char** argv) { + LibraryInitializer libInit; ::benchmark::Initialize(&argc, argv); ::grpc::testing::InitTest(&argc, &argv, false); benchmark::RunTheBenchmarksNamespaced(); diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h index 80ccab3e6ef..075a09c63eb 100644 --- a/test/cpp/microbenchmarks/fullstack_fixtures.h +++ b/test/cpp/microbenchmarks/fullstack_fixtures.h @@ -299,8 +299,8 @@ class InProcessCHTTP2WithExplicitStats : public EndpointPairFixture { static grpc_endpoint_pair MakeEndpoints(grpc_passthru_endpoint_stats* stats) { grpc_endpoint_pair p; - grpc_passthru_endpoint_create(&p.client, &p.server, Library::get().rq(), - stats); + grpc_passthru_endpoint_create(&p.client, &p.server, + LibraryInitializer::get().rq(), stats); return p; } }; diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc index d4070de7481..7d78e21aef7 100644 --- a/test/cpp/microbenchmarks/helpers.cc +++ b/test/cpp/microbenchmarks/helpers.cc @@ -21,8 +21,12 @@ #include "test/cpp/microbenchmarks/helpers.h" static grpc::internal::GrpcLibraryInitializer g_gli_initializer; +static LibraryInitializer* g_libraryInitializer; + +LibraryInitializer::LibraryInitializer() { + GPR_ASSERT(g_libraryInitializer == nullptr); + g_libraryInitializer = this; -Library::Library() { g_gli_initializer.summon(); #ifdef GPR_LOW_LEVEL_COUNTERS grpc_memory_counters_init(); @@ -31,6 +35,17 @@ Library::Library() { rq_ = grpc_resource_quota_create("bm"); } +LibraryInitializer::~LibraryInitializer() { + g_libraryInitializer = nullptr; + init_lib_.shutdown(); + grpc_resource_quota_unref(rq_); +} + +LibraryInitializer& LibraryInitializer::get() { + GPR_ASSERT(g_libraryInitializer != nullptr); + return *g_libraryInitializer; +} + void TrackCounters::Finish(benchmark::State& state) { std::ostringstream out; for (const auto& l : labels_) { diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h index 770966aa189..b712c85d354 100644 --- a/test/cpp/microbenchmarks/helpers.h +++ b/test/cpp/microbenchmarks/helpers.h @@ -29,20 +29,16 @@ #include #include -class Library { +class LibraryInitializer { public: - static Library& get() { - static Library lib; - return lib; - } + LibraryInitializer(); + ~LibraryInitializer(); grpc_resource_quota* rq() { return rq_; } - private: - Library(); - - ~Library() { init_lib_.shutdown(); } + static LibraryInitializer& get(); + private: grpc::internal::GrpcLibrary init_lib_; grpc_resource_quota* rq_; };