json_run_localhost.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015-2016 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 
19 #include <signal.h>
20 #include <string.h>
21 
22 #include <memory>
23 #include <mutex>
24 #include <sstream>
25 #include <string>
26 
27 #ifdef __FreeBSD__
28 #include <sys/wait.h>
29 #endif
30 
31 #include <grpc/support/log.h>
32 
33 #include "src/core/lib/gpr/env.h"
34 #include "test/core/util/port.h"
36 
37 using grpc::SubProcess;
38 
39 constexpr auto kNumWorkers = 2;
40 
43 
44 template <class T>
45 std::string as_string(const T& val) {
46  std::ostringstream out;
47  out << val;
48  return out.str();
49 }
50 
51 static void sighandler(int /*sig*/) {
52  const int errno_saved = errno;
53  if (g_driver != nullptr) g_driver->Interrupt();
54  for (int i = 0; i < kNumWorkers; ++i) {
55  if (g_workers[i]) g_workers[i]->Interrupt();
56  }
57  errno = errno_saved;
58 }
59 
60 static void register_sighandler() {
61  struct sigaction act;
62  memset(&act, 0, sizeof(act));
63  act.sa_handler = sighandler;
64 
65  sigaction(SIGINT, &act, nullptr);
66  sigaction(SIGTERM, &act, nullptr);
67 }
68 
69 static void LogStatus(int status, const char* label) {
70  if (WIFEXITED(status)) {
71  gpr_log(GPR_INFO, "%s: subprocess exited with status %d", label,
72  WEXITSTATUS(status));
73  } else if (WIFSIGNALED(status)) {
74  gpr_log(GPR_INFO, "%s: subprocess terminated with signal %d", label,
75  WTERMSIG(status));
76  } else {
77  gpr_log(GPR_INFO, "%s: unknown subprocess status: %d", label, status);
78  }
79 }
80 
81 int main(int argc, char** argv) {
83 
84  std::string my_bin = argv[0];
85  std::string bin_dir = my_bin.substr(0, my_bin.rfind('/'));
86 
87  std::ostringstream env;
88  bool first = true;
89 
90  for (int i = 0; i < kNumWorkers; i++) {
91  const auto driver_port = grpc_pick_unused_port_or_die();
92  // ServerPort can be used or not later depending on the type of worker
93  // but we like to issue all ports required here to avoid port conflict.
95  std::vector<std::string> args = {bin_dir + "/qps_worker", "-driver_port",
96  as_string(driver_port), "-server_port",
98  g_workers[i] = new SubProcess(args);
99  if (!first) env << ",";
100  env << "localhost:" << driver_port;
101  first = false;
102  }
103 
104  gpr_setenv("QPS_WORKERS", env.str().c_str());
105  std::vector<std::string> args = {bin_dir + "/qps_json_driver"};
106  for (int i = 1; i < argc; i++) {
107  args.push_back(argv[i]);
108  }
109 
110  g_driver = new SubProcess(args);
111  const int driver_join_status = g_driver->Join();
112  if (driver_join_status != 0) {
113  LogStatus(driver_join_status, "driver");
114  }
115  for (int i = 0; i < kNumWorkers; ++i) {
116  if (g_workers[i]) g_workers[i]->Interrupt();
117  }
118 
119  for (int i = 0; i < kNumWorkers; ++i) {
120  if (g_workers[i]) {
121  const int worker_status = g_workers[i]->Join();
122  if (worker_status != 0) {
123  LogStatus(worker_status, "worker");
124  }
125  }
126  }
127 
128  delete g_driver;
129 
130  g_driver = nullptr;
131  for (int i = 0; i < kNumWorkers; ++i) {
132  if (g_workers[i] != nullptr) {
133  delete g_workers[i];
134  }
135  }
136  GPR_ASSERT(driver_join_status == 0);
137 }
grpc::SubProcess::Join
int Join()
Definition: test/cpp/util/subprocess.cc:40
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
log.h
port.h
generate.env
env
Definition: generate.py:37
memset
return memset(p, 0, total)
grpc::SubProcess::Interrupt
void Interrupt()
Definition: test/cpp/util/subprocess.cc:42
string.h
server_port
static int server_port
Definition: bad_server_response_test.cc:86
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
status
absl::Status status
Definition: rls.cc:251
env.h
main
int main(int argc, char **argv)
Definition: json_run_localhost.cc:81
T
#define T(upbtypeconst, upbtype, ctype, default_value)
register_sighandler
static void register_sighandler()
Definition: json_run_localhost.cc:60
subprocess.h
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
gen_synthetic_protos.label
label
Definition: gen_synthetic_protos.py:102
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
grpc::SubProcess
Definition: test/cpp/util/subprocess.h:30
grpc_pick_unused_port_or_die
int grpc_pick_unused_port_or_die(void)
kNumWorkers
constexpr auto kNumWorkers
Definition: json_run_localhost.cc:39
g_workers
static SubProcess * g_workers[kNumWorkers]
Definition: json_run_localhost.cc:42
LogStatus
static void LogStatus(int status, const char *label)
Definition: json_run_localhost.cc:69
sighandler
static void sighandler(int)
Definition: json_run_localhost.cc:51
first
StrT first
Definition: cxa_demangle.cpp:4884
env
Definition: env.py:1
as_string
std::string as_string(const T &val)
Definition: json_run_localhost.cc:45
g_driver
static SubProcess * g_driver
Definition: json_run_localhost.cc:41
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
gpr_setenv
void gpr_setenv(const char *name, const char *value)


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