• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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