1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <chrono>
18 #include <memory>
19
20 #include <grpcpp/client_context.h>
21 #include <grpcpp/grpcpp.h>
22
23 #include "perfetto/base/status.h"
24 #include "perfetto/ext/base/getopt.h"
25 #include "protos/perfetto/bigtrace/orchestrator.grpc.pb.h"
26 #include "protos/perfetto/bigtrace/orchestrator.pb.h"
27 #include "protos/perfetto/bigtrace/worker.grpc.pb.h"
28 #include "protos/perfetto/bigtrace/worker.pb.h"
29
30 namespace perfetto {
31 namespace bigtrace {
32 namespace {
33
34 struct CommandLineOptions {
35 std::string worker_address;
36 };
37
ParseCommandLineOptions(int argc,char ** argv)38 CommandLineOptions ParseCommandLineOptions(int argc, char** argv) {
39 CommandLineOptions command_line_options;
40 static option long_options[] = {{"worker", required_argument, nullptr, 'w'},
41 {nullptr, 0, nullptr, 0}};
42 int c;
43 while ((c = getopt_long(argc, argv, "w:", long_options, nullptr)) != -1) {
44 switch (c) {
45 case 'w':
46 command_line_options.worker_address = optarg;
47 break;
48 default:
49 PERFETTO_ELOG("Usage: %s --worker=worker_address", argv[0]);
50 break;
51 }
52 }
53
54 return command_line_options;
55 }
56
57 class OrchestratorImpl final : public protos::BigtraceOrchestrator::Service {
Query(grpc::ServerContext *,const protos::BigtraceQueryArgs *,grpc::ServerWriter<protos::BigtraceQueryResponse> *)58 grpc::Status Query(
59 grpc::ServerContext*,
60 const protos::BigtraceQueryArgs*,
61 grpc::ServerWriter<protos::BigtraceQueryResponse>*) override {
62 return grpc::Status::OK;
63 }
64 };
65
OrchestratorMain(int argc,char ** argv)66 base::Status OrchestratorMain(int argc, char** argv) {
67 CommandLineOptions options = ParseCommandLineOptions(argc, argv);
68
69 std::string server_address("localhost:5051");
70 std::string worker_address = !options.worker_address.empty()
71 ? options.worker_address
72 : "localhost:5052";
73
74 // Setup the Orchestrator Server
75 auto service = std::make_unique<OrchestratorImpl>();
76 grpc::ServerBuilder builder;
77 builder.RegisterService(service.get());
78 builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
79
80 // Setup the Orchestrator Client
81 auto channel =
82 grpc::CreateChannel(worker_address, grpc::InsecureChannelCredentials());
83 bool connected = channel->WaitForConnected(std::chrono::system_clock::now() +
84 std::chrono::milliseconds(5000));
85
86 PERFETTO_CHECK(connected);
87
88 std::string example_trace = "test/data/api34_startup_cold.perfetto-trace";
89 std::string example_query = "SELECT * FROM slice";
90
91 auto stub = protos::BigtraceWorker::NewStub(channel);
92 grpc::ClientContext context;
93 protos::BigtraceQueryTraceArgs args;
94 protos::BigtraceQueryTraceResponse response;
95
96 args.set_trace(example_trace);
97 args.set_sql_query(example_query);
98
99 grpc::Status status = stub->QueryTrace(&context, args, &response);
100
101 if (status.ok()) {
102 PERFETTO_LOG("Received response with result_size: %i",
103 response.result_size());
104 } else {
105 PERFETTO_LOG("Failed to query trace");
106 }
107
108 // Build and start the Orchestrator server
109 std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
110 PERFETTO_LOG("Orchestrator server listening on %s", server_address.c_str());
111
112 server->Wait();
113
114 return base::OkStatus();
115 }
116
117 } // namespace
118 } // namespace bigtrace
119 } // namespace perfetto
120
main(int argc,char ** argv)121 int main(int argc, char** argv) {
122 auto status = perfetto::bigtrace::OrchestratorMain(argc, argv);
123 if (!status.ok()) {
124 fprintf(stderr, "%s\n", status.c_message());
125 return 1;
126 }
127 return 0;
128 }
129