summaryrefslogtreecommitdiffstats
path: root/src/main-grpc.cc
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2023-01-03 00:51:50 -0500
committerScott Murray <scott.murray@konsulko.com>2023-01-19 00:37:11 +0000
commit7f26a2d06410fd3a2768612b9c9daf869778e480 (patch)
tree4dfffa78e14c8eadb42a731ae15cc87137e17723 /src/main-grpc.cc
parent6191be9c1e4b628f60ccaeabcef2aaa9de00800b (diff)
Repurpose into gRPC service
Repurpose repository into a spiritual successor of the previous binding. The backend code is retained behind a new gRPC API defined in protos/radio.proto. The simpler synchronous gRPC API had been used for expediency, this may warrant revisiting to rework into an async or callback API based server instead. As well, authentication has been left until some consensus on an approach can be worked out. Bug-AGL: SPEC-4665 Signed-off-by: Scott Murray <scott.murray@konsulko.com> Change-Id: I28b122ce6e0ecfc7504aa08b90394cb1b9e22976 (cherry picked from commit dd23c157bdba1b25bbb50cdb99a60aa597735f43)
Diffstat (limited to 'src/main-grpc.cc')
-rw-r--r--src/main-grpc.cc83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/main-grpc.cc b/src/main-grpc.cc
new file mode 100644
index 0000000..29e01f1
--- /dev/null
+++ b/src/main-grpc.cc
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: Apache-2.0
+/*
+ * Copyright (C) 2023 Konsulko Group
+ */
+
+#include <thread>
+#include <chrono>
+#include <glib.h>
+#include <glib-unix.h>
+
+#include "RadioImpl.h"
+
+GMainLoop *main_loop = NULL;
+
+RadioImpl *g_service = NULL;
+
+static gboolean quit_cb(gpointer user_data)
+{
+ g_info("Quitting...");
+
+ if (main_loop)
+ g_idle_add(G_SOURCE_FUNC(g_main_loop_quit), main_loop);
+ else
+ exit(0);
+
+ return G_SOURCE_REMOVE;
+}
+
+void RunGrpcServer(std::shared_ptr<Server> &server)
+{
+ // Start server and wait for shutdown
+ server->Wait();
+}
+
+int main(int argc, char *argv[])
+{
+ main_loop = g_main_loop_new(NULL, FALSE);
+
+ grpc::EnableDefaultHealthCheckService(true);
+ grpc::reflection::InitProtoReflectionServerBuilderPlugin();
+ ServerBuilder builder;
+
+ // Listen on the given address without any authentication mechanism (for now)
+ std::string server_address("localhost:50053");
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to a *synchronous* service.
+ RadioImpl *service = new RadioImpl();
+ if (!service->Detect()) {
+ exit(1);
+ }
+ builder.RegisterService(service);
+
+ // Finally assemble the server.
+ std::shared_ptr<Server> server(builder.BuildAndStart());
+ if (!server) {
+ exit(1);
+ }
+ std::cout << "Server listening on " << server_address << std::endl;
+
+ g_unix_signal_add(SIGTERM, quit_cb, (gpointer) &server);
+ g_unix_signal_add(SIGINT, quit_cb, (gpointer) &server);
+
+ // Start gRPC API server on its own thread
+ std::thread grpc_thread(RunGrpcServer, std::ref(server));
+
+ g_main_loop_run(main_loop);
+
+ // Service implementation may have threads blocked from client streaming
+ // RPCs, make sure those exit.
+ service->Shutdown();
+
+ // Need to set a deadline to avoid blocking on clients doing streaming
+ // RPC reads
+ server->Shutdown(std::chrono::system_clock::now() + std::chrono::milliseconds(500));
+
+ grpc_thread.join();
+
+ g_main_loop_unref(main_loop);
+
+ return 0;
+}