port_server_client.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #ifdef GRPC_TEST_PICK_PORT
24 #include <math.h>
25 #include <string.h>
26 
27 #include "absl/strings/str_format.h"
28 
29 #include <grpc/grpc.h>
30 #include <grpc/grpc_security.h>
31 #include <grpc/support/alloc.h>
32 #include <grpc/support/log.h>
34 #include <grpc/support/sync.h>
35 #include <grpc/support/time.h>
36 
40 
41 typedef struct freereq {
42  gpr_mu* mu = nullptr;
43  grpc_polling_entity pops = {};
44  int done = 0;
45 } freereq;
46 
47 static void destroy_pops_and_shutdown(void* p, grpc_error_handle /*error*/) {
48  grpc_pollset* pollset =
50  grpc_pollset_destroy(pollset);
51  gpr_free(pollset);
52 }
53 
54 static void freed_port_from_server(void* arg, grpc_error_handle /*error*/) {
55  freereq* pr = static_cast<freereq*>(arg);
56  gpr_mu_lock(pr->mu);
57  pr->done = 1;
59  "pollset_kick",
60  grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), nullptr));
61  gpr_mu_unlock(pr->mu);
62 }
63 
67  freereq pr;
68  grpc_closure* shutdown_closure;
69 
70  grpc_init();
71  {
73 
74  pr = {};
75  memset(&req, 0, sizeof(req));
76  rsp = {};
77 
78  grpc_pollset* pollset =
79  static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
80  grpc_pollset_init(pollset, &pr.mu);
81  pr.pops = grpc_polling_entity_create_from_pollset(pollset);
82  shutdown_closure = GRPC_CLOSURE_CREATE(destroy_pops_and_shutdown, &pr.pops,
83  grpc_schedule_on_exec_ctx);
84 
85  std::string path = absl::StrFormat("/drop/%d", port);
87  {} /* query params */, "" /* fragment */);
88  GPR_ASSERT(uri.ok());
89  auto http_request = grpc_core::HttpRequest::Get(
90  std::move(*uri), nullptr /* channel args */, &pr.pops, &req,
92  GRPC_CLOSURE_CREATE(freed_port_from_server, &pr,
93  grpc_schedule_on_exec_ctx),
94  &rsp,
97  http_request->Start();
99  gpr_mu_lock(pr.mu);
100  while (!pr.done) {
101  grpc_pollset_worker* worker = nullptr;
102  if (!GRPC_LOG_IF_ERROR(
103  "pollset_work",
107  pr.done = 1;
108  }
109  }
110  gpr_mu_unlock(pr.mu);
111 
113  shutdown_closure);
114 
116  }
117  grpc_shutdown();
118 }
119 
120 typedef struct portreq {
121  gpr_mu* mu = nullptr;
122  grpc_polling_entity pops = {};
123  int port = 0;
124  int retries = 0;
125  char* server = nullptr;
128 } portreq;
129 
130 static void got_port_from_server(void* arg, grpc_error_handle error) {
131  size_t i;
132  int port = 0;
133  portreq* pr = static_cast<portreq*>(arg);
134  pr->http_request.reset();
135  int failed = 0;
136  grpc_http_response* response = &pr->response;
137 
138  if (!GRPC_ERROR_IS_NONE(error)) {
139  failed = 1;
140  gpr_log(GPR_DEBUG, "failed port pick from server: retrying [%s]",
142  } else if (response->status != 200) {
143  failed = 1;
144  gpr_log(GPR_DEBUG, "failed port pick from server: status=%d",
145  response->status);
146  }
147 
148  if (failed) {
150  memset(&req, 0, sizeof(req));
151  if (pr->retries >= 5) {
152  gpr_mu_lock(pr->mu);
153  pr->port = 0;
155  "pollset_kick",
156  grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), nullptr));
157  gpr_mu_unlock(pr->mu);
158  return;
159  }
160  GPR_ASSERT(pr->retries < 10);
164  static_cast<int64_t>(
165  1000.0 * (1 + pow(1.3, pr->retries) * rand() / RAND_MAX)),
166  GPR_TIMESPAN)));
167  pr->retries++;
168  grpc_http_response_destroy(&pr->response);
169  pr->response = {};
170  auto uri = grpc_core::URI::Create("http", pr->server, "/get",
171  {} /* query params */, "" /* fragment */);
172  GPR_ASSERT(uri.ok());
173  pr->http_request = grpc_core::HttpRequest::Get(
174  std::move(*uri), nullptr /* channel args */, &pr->pops, &req,
176  GRPC_CLOSURE_CREATE(got_port_from_server, pr,
177  grpc_schedule_on_exec_ctx),
178  &pr->response,
181  pr->http_request->Start();
182  return;
183  }
185  GPR_ASSERT(response->status == 200);
186  for (i = 0; i < response->body_length; i++) {
187  GPR_ASSERT(response->body[i] >= '0' && response->body[i] <= '9');
188  port = port * 10 + response->body[i] - '0';
189  }
190  GPR_ASSERT(port > 1024);
191  gpr_mu_lock(pr->mu);
192  pr->port = port;
194  "pollset_kick",
195  grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), nullptr));
196  gpr_mu_unlock(pr->mu);
197 }
198 
199 int grpc_pick_port_using_server(void) {
201  portreq pr;
202  grpc_closure* shutdown_closure;
203 
204  grpc_init();
205  {
207  pr = {};
208  memset(&req, 0, sizeof(req));
209  grpc_pollset* pollset =
210  static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
211  grpc_pollset_init(pollset, &pr.mu);
212  pr.pops = grpc_polling_entity_create_from_pollset(pollset);
213  shutdown_closure = GRPC_CLOSURE_CREATE(destroy_pops_and_shutdown, &pr.pops,
214  grpc_schedule_on_exec_ctx);
215  pr.port = -1;
216  pr.server = const_cast<char*>(GRPC_PORT_SERVER_ADDRESS);
217  auto uri = grpc_core::URI::Create("http", GRPC_PORT_SERVER_ADDRESS, "/get",
218  {} /* query params */, "" /* fragment */);
219  GPR_ASSERT(uri.ok());
220  auto http_request = grpc_core::HttpRequest::Get(
221  std::move(*uri), nullptr /* channel args */, &pr.pops, &req,
223  GRPC_CLOSURE_CREATE(got_port_from_server, &pr,
224  grpc_schedule_on_exec_ctx),
225  &pr.response,
228  http_request->Start();
230  gpr_mu_lock(pr.mu);
231  while (pr.port == -1) {
232  grpc_pollset_worker* worker = nullptr;
233  if (!GRPC_LOG_IF_ERROR(
234  "pollset_work",
238  pr.port = 0;
239  }
240  }
241  gpr_mu_unlock(pr.mu);
242 
243  grpc_http_response_destroy(&pr.response);
245  shutdown_closure);
246 
248  }
249  grpc_shutdown();
250 
251  return pr.port;
252 }
253 
254 #endif // GRPC_TEST_PICK_PORT
grpc_pollset_worker
struct grpc_pollset_worker grpc_pollset_worker
Definition: pollset.h:39
GPR_TIMESPAN
@ GPR_TIMESPAN
Definition: gpr_types.h:45
grpc_pollset_size
size_t grpc_pollset_size(void)
Definition: pollset.cc:56
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
grpc_polling_entity_pollset
grpc_pollset * grpc_polling_entity_pollset(grpc_polling_entity *pollent)
Definition: polling_entity.cc:42
log.h
memset
return memset(p, 0, total)
port_server_client.h
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
string.h
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
error
grpc_error_handle error
Definition: retry_filter.cc:499
grpc_pollset_work
grpc_error_handle grpc_pollset_work(grpc_pollset *pollset, grpc_pollset_worker **worker, grpc_core::Timestamp deadline)
Definition: pollset.cc:45
GRPC_LOG_IF_ERROR
#define GRPC_LOG_IF_ERROR(what, error)
Definition: error.h:398
time.h
check_documentation.path
path
Definition: check_documentation.py:57
xds_manager.p
p
Definition: xds_manager.py:60
GRPC_CLOSURE_CREATE
#define GRPC_CLOSURE_CREATE(cb, cb_arg, scheduler)
Definition: closure.h:160
grpc_security.h
credentials.h
GRPC_PORT_SERVER_ADDRESS
#define GRPC_PORT_SERVER_ADDRESS
Definition: port_server_client.h:25
grpc_pollset_init
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu)
Definition: pollset.cc:33
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
string_util.h
grpc_http_response
Definition: src/core/lib/http/parser.h:85
grpc_core::RefCountedPtr< grpc_channel_credentials >
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
grpc_core::ExecCtx::Flush
bool Flush()
Definition: exec_ctx.cc:69
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
req
static uv_connect_t req
Definition: test-connection-fail.c:30
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
worker
Definition: worker.py:1
grpc_polling_entity_create_from_pollset
grpc_polling_entity grpc_polling_entity_create_from_pollset(grpc_pollset *pollset)
Definition: polling_entity.cc:34
gpr_sleep_until
GPRAPI void gpr_sleep_until(gpr_timespec until)
httpcli.h
grpc.h
grpc_insecure_credentials_create
GRPCAPI grpc_channel_credentials * grpc_insecure_credentials_create()
Definition: core/lib/security/credentials/insecure/insecure_credentials.cc:64
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
arg
Definition: cmdline.cc:40
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
grpc_http_response_destroy
void grpc_http_response_destroy(grpc_http_response *response)
Definition: src/core/lib/http/parser.cc:434
grpc_free_port_using_server
void grpc_free_port_using_server(int port)
grpc_polling_entity
Definition: polling_entity.h:38
grpc_pollset_kick
grpc_error_handle grpc_pollset_kick(grpc_pollset *pollset, grpc_pollset_worker *specific_worker)
Definition: pollset.cc:51
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
grpc_core::ExecCtx
Definition: exec_ctx.h:97
tests.unit._exit_scenarios.port
port
Definition: _exit_scenarios.py:179
test_config.h
grpc_core::HttpRequest::Get
static OrphanablePtr< HttpRequest > Get(URI uri, const grpc_channel_args *args, grpc_polling_entity *pollent, const grpc_http_request *request, Timestamp deadline, grpc_closure *on_done, grpc_http_response *response, RefCountedPtr< grpc_channel_credentials > channel_creds) GRPC_MUST_USE_RESULT
Definition: httpcli.cc:69
gpr_time_add
GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:135
server
Definition: examples/python/async_streaming/server.py:1
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
grpc_error_std_string
std::string grpc_error_std_string(grpc_error_handle error)
Definition: error.cc:944
grpc_pollset_shutdown
void grpc_pollset_shutdown(grpc_pollset *pollset, grpc_closure *closure)
Definition: pollset.cc:37
grpc_core::URI::Create
static absl::StatusOr< URI > Create(std::string scheme, std::string authority, std::string path, std::vector< QueryParam > query_parameter_pairs, std::string fragment)
Definition: uri_parser.cc:289
alloc.h
grpc_core::OrphanablePtr
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:64
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc_core::Duration::Seconds
static constexpr Duration Seconds(int64_t seconds)
Definition: src/core/lib/gprpp/time.h:151
arg
struct arg arg
gpr_time_from_millis
GPRAPI gpr_timespec gpr_time_from_millis(int64_t ms, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:119
grpc_pick_port_using_server
int grpc_pick_port_using_server(void)
GPR_DEBUG
#define GPR_DEBUG
Definition: include/grpc/impl/codegen/log.h:55
grpc_core::ExecCtx::Now
Timestamp Now()
Definition: exec_ctx.cc:90
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
grpc_error
Definition: error_internal.h:42
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
grpc_pollset
Definition: bm_cq_multiple_threads.cc:37
grpc_pollset_destroy
void grpc_pollset_destroy(grpc_pollset *pollset)
Definition: pollset.cc:41
sync.h
grpc_closure
Definition: closure.h:56
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
GRPC_ERROR_IS_NONE
#define GRPC_ERROR_IS_NONE(err)
Definition: error.h:241
grpc_http_request
Definition: src/core/lib/http/parser.h:69
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:54