bigtrace: Add initial serviceless gRPC server for Orchestrator and Worker

- Add serviceless GRPC servers on localhost for Orchestrator and Worker
- Add client channel in Orchestrator to connect to a single Worker

Change-Id: I04c47d797e78174a3be7a667e225a78bcab1a32a
diff --git a/BUILD.gn b/BUILD.gn
index 35ea4ea..6e80df5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -45,8 +45,10 @@
 }
 
 if (enable_perfetto_trace_processor && enable_perfetto_trace_processor_sqlite) {
-  all_targets += [ "src/bigtrace:orchestrator_main" ]
-  all_targets += [ "src/bigtrace:worker_main" ]
+  if (enable_perfetto_grpc) {
+    all_targets += [ "src/bigtrace:orchestrator_main" ]
+    all_targets += [ "src/bigtrace:worker_main" ]
+  }
   all_targets += [ "src/trace_processor:trace_processor_shell" ]
 }
 
diff --git a/src/bigtrace/BUILD.gn b/src/bigtrace/BUILD.gn
index 4d4a03c..734435c 100644
--- a/src/bigtrace/BUILD.gn
+++ b/src/bigtrace/BUILD.gn
@@ -18,12 +18,22 @@
 assert(
     enable_perfetto_trace_processor && enable_perfetto_trace_processor_sqlite)
 
-executable("orchestrator_main") {
-  sources = [ "orchestrator_main.cc" ]
-  deps = [ "../../gn:default_deps" ]
-}
+if (enable_perfetto_grpc) {
+  executable("orchestrator_main") {
+    sources = [ "orchestrator_main.cc" ]
+    deps = [
+      "../../gn:default_deps",
+      "../../gn:grpc",
+      "../base",
+    ]
+  }
 
-executable("worker_main") {
-  sources = [ "worker_main.cc" ]
-  deps = [ "../../gn:default_deps" ]
+  executable("worker_main") {
+    sources = [ "worker_main.cc" ]
+    deps = [
+      "../../gn:default_deps",
+      "../../gn:grpc",
+      "../base",
+    ]
+  }
 }
diff --git a/src/bigtrace/orchestrator_main.cc b/src/bigtrace/orchestrator_main.cc
index 9d16293..0a0a4b7 100644
--- a/src/bigtrace/orchestrator_main.cc
+++ b/src/bigtrace/orchestrator_main.cc
@@ -14,6 +14,46 @@
  * limitations under the License.
  */
 
-int main(int, char**) {
+#include <chrono>
+
+#include <grpcpp/grpcpp.h>
+
+#include "perfetto/base/status.h"
+
+namespace perfetto {
+namespace bigtrace {
+namespace {
+
+base::Status OrchestratorMain(int, char**) {
+  std::string server_address("127.0.0.1:5051");
+  grpc::ServerBuilder builder;
+  auto cq = builder.AddCompletionQueue();
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+
+  auto channel =
+      grpc::CreateChannel("localhost:5052", grpc::InsecureChannelCredentials());
+  bool connected = channel->WaitForConnected(std::chrono::system_clock::now() +
+                                             std::chrono::milliseconds(5000));
+
+  PERFETTO_CHECK(connected);
+
+  std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+  PERFETTO_LOG("Orchestrator server listening on %s", server_address.c_str());
+
+  server->Wait();
+
+  return base::OkStatus();
+}
+
+}  // namespace
+}  // namespace bigtrace
+}  // namespace perfetto
+
+int main(int argc, char** argv) {
+  auto status = perfetto::bigtrace::OrchestratorMain(argc, argv);
+  if (!status.ok()) {
+    fprintf(stderr, "%s\n", status.c_message());
+    return 1;
+  }
   return 0;
 }
diff --git a/src/bigtrace/worker_main.cc b/src/bigtrace/worker_main.cc
index 9d16293..2b877d7 100644
--- a/src/bigtrace/worker_main.cc
+++ b/src/bigtrace/worker_main.cc
@@ -14,6 +14,36 @@
  * limitations under the License.
  */
 
-int main(int, char**) {
+#include <grpcpp/grpcpp.h>
+
+#include "perfetto/base/status.h"
+
+namespace perfetto {
+namespace bigtrace {
+namespace {
+
+base::Status WorkerMain(int, char**) {
+  std::string server_address("127.0.0.1:5052");
+  grpc::ServerBuilder builder;
+  auto cq = builder.AddCompletionQueue();
+  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+  std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+  PERFETTO_LOG("Orchestrator server listening on %s", server_address.c_str());
+
+  server->Wait();
+
+  return base::OkStatus();
+}
+
+}  // namespace
+}  // namespace bigtrace
+}  // namespace perfetto
+
+int main(int argc, char** argv) {
+  auto status = perfetto::bigtrace::WorkerMain(argc, argv);
+  if (!status.ok()) {
+    fprintf(stderr, "%s\n", status.c_message());
+    return 1;
+  }
   return 0;
 }