diff options
author | 2023-01-03 00:51:50 -0500 | |
---|---|---|
committer | 2023-01-19 00:37:11 +0000 | |
commit | 7f26a2d06410fd3a2768612b9c9daf869778e480 (patch) | |
tree | 4dfffa78e14c8eadb42a731ae15cc87137e17723 /src/main-grpc.cc | |
parent | 6191be9c1e4b628f60ccaeabcef2aaa9de00800b (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.cc | 83 |
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; +} |