LCOV - code coverage report
Current view: top level - src/UserTimelineService - UserTimelineService.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 52 80 65.0 %
Date: 2025-11-04 01:35:31 Functions: 4 5 80.0 %

          Line data    Source code
       1             : #include <signal.h>
       2             : #include <thrift/protocol/TBinaryProtocol.h>
       3             : #include <thrift/server/TThreadedServer.h>
       4             : #include <thrift/transport/TBufferTransports.h>
       5             : #include <thrift/transport/TServerSocket.h>
       6             : 
       7             : #include <boost/program_options.hpp>
       8             : 
       9             : #include "../../gen-cpp/social_network_types.h"
      10             : #include "../ClientPool.h"
      11             : #include "../logger.h"
      12             : #include "../tracing.h"
      13             : #include "../utils.h"
      14             : #include "../utils_mongodb.h"
      15             : #include "../utils_redis.h"
      16             : #include "../utils_thrift.h"
      17             : #include "UserTimelineHandler.h"
      18             : 
      19             : extern "C" void __gcov_flush();
      20             : 
      21             : using apache::thrift::protocol::TBinaryProtocolFactory;
      22             : using apache::thrift::server::TThreadedServer;
      23             : using apache::thrift::transport::TFramedTransportFactory;
      24             : using apache::thrift::transport::TServerSocket;
      25             : using namespace social_network;
      26             : 
      27           0 : void sigintHandler(int sig) { exit(EXIT_SUCCESS); }
      28             : 
      29           1 : void handle_sigusr1(int signum) {
      30           1 :   __gcov_flush();
      31           0 : }
      32             : 
      33           1 : int main(int argc, char *argv[]) {
      34           1 :   signal(SIGINT, sigintHandler);
      35           1 :   signal(SIGUSR1, handle_sigusr1);
      36           1 :   init_logger();
      37             : 
      38             :   // Command line options
      39             :   namespace po = boost::program_options;
      40           1 :   po::options_description desc("Options");
      41           2 :   desc.add_options()("help", "produce help message")(
      42             :       "redis-cluster",
      43           2 :       po::value<bool>()->default_value(false)->implicit_value(true),
      44           1 :       "Enable redis cluster mode");
      45             : 
      46           1 :   po::variables_map vm;
      47           1 :   po::store(po::parse_command_line(argc, argv, desc), vm);
      48           1 :   po::notify(vm);
      49             : 
      50           1 :   if (vm.count("help")) {
      51           0 :     std::cout << desc << "\n";
      52           0 :     return 0;
      53             :   }
      54             : 
      55           1 :   bool redis_cluster_flag = false;
      56           1 :   if (vm.count("redis-cluster")) {
      57           1 :     if (vm["redis-cluster"].as<bool>()) {
      58           0 :       redis_cluster_flag = true;
      59             :     }
      60             :   }
      61             : 
      62           1 :   SetUpTracer("config/jaeger-config.yml", "user-timeline-service");
      63             : 
      64           1 :   json config_json;
      65           1 :   if (load_config_file("config/service-config.json", &config_json) != 0) {
      66           0 :     exit(EXIT_FAILURE);
      67             :   }
      68             : 
      69           1 :   int port = config_json["user-timeline-service"]["port"];
      70             : 
      71           1 :   int post_storage_port = config_json["post-storage-service"]["port"];
      72           1 :   std::string post_storage_addr = config_json["post-storage-service"]["addr"];
      73           1 :   int post_storage_conns = config_json["post-storage-service"]["connections"];
      74           1 :   int post_storage_timeout = config_json["post-storage-service"]["timeout_ms"];
      75             :   int post_storage_keepalive =
      76           1 :       config_json["post-storage-service"]["keepalive_ms"];
      77             : 
      78           1 :   int mongodb_conns = config_json["user-timeline-mongodb"]["connections"];
      79           1 :   int mongodb_timeout = config_json["user-timeline-mongodb"]["timeout_ms"];
      80             : 
      81           1 :   int redis_cluster_config_flag = config_json["user-timeline-redis"]["use_cluster"];
      82           1 :   int redis_replica_config_flag = config_json["user-timeline-redis"]["use_replica"];
      83             : 
      84             :   auto mongodb_client_pool =
      85           1 :       init_mongodb_client_pool(config_json, "user-timeline", mongodb_conns);
      86             : 
      87           1 :   if (mongodb_client_pool == nullptr) {
      88           0 :     return EXIT_FAILURE;
      89             :   }
      90             : 
      91           1 :   if (redis_replica_config_flag && (redis_cluster_config_flag || redis_cluster_flag)) {
      92           0 :       LOG(error) << "Can't start service when Redis Cluster and Redis Replica are enabled at the same time";
      93           0 :       exit(EXIT_FAILURE);
      94             :   }
      95             : 
      96             :   ClientPool<ThriftClient<PostStorageServiceClient>> post_storage_client_pool(
      97             :       "post-storage-client", post_storage_addr, post_storage_port, 0,
      98             :       post_storage_conns, post_storage_timeout, post_storage_keepalive,
      99           1 :       config_json);
     100             : 
     101           1 :   mongoc_client_t *mongodb_client = mongoc_client_pool_pop(mongodb_client_pool);
     102           1 :   if (!mongodb_client) {
     103           0 :     LOG(fatal) << "Failed to pop mongoc client";
     104           0 :     return EXIT_FAILURE;
     105             :   }
     106           1 :   bool r = false;
     107           3 :   while (!r) {
     108           1 :     r = CreateIndex(mongodb_client, "user-timeline", "user_id", true);
     109           1 :     if (!r) {
     110           0 :       LOG(error) << "Failed to create mongodb index, try again";
     111           0 :       sleep(1);
     112             :     }
     113             :   }
     114           1 :   mongoc_client_pool_push(mongodb_client_pool, mongodb_client);
     115             :   std::shared_ptr<TServerSocket> server_socket =
     116           1 :       get_server_socket(config_json, "0.0.0.0", port);
     117             : 
     118           1 :   if (redis_cluster_flag || redis_cluster_config_flag) {
     119             :     RedisCluster redis_client_pool =
     120           0 :         init_redis_cluster_client_pool(config_json, "user-timeline");
     121           0 :     TThreadedServer server(std::make_shared<UserTimelineServiceProcessor>(
     122           0 :                                std::make_shared<UserTimelineHandler>(
     123             :                                    &redis_client_pool, mongodb_client_pool,
     124             :                                    &post_storage_client_pool)),
     125             :                            server_socket,
     126           0 :                            std::make_shared<TFramedTransportFactory>(),
     127           0 :                            std::make_shared<TBinaryProtocolFactory>());
     128           0 :     LOG(info) << "Starting the user-timeline-service server with Redis Cluster support...";
     129           0 :     server.serve();
     130             :   }
     131           1 :   else if (redis_replica_config_flag) {
     132           0 :       Redis redis_replica_client_pool = init_redis_replica_client_pool(config_json, "redis-replica");
     133           0 :       Redis redis_primary_client_pool = init_redis_replica_client_pool(config_json, "redis-primary");
     134           0 :       TThreadedServer server(std::make_shared<UserTimelineServiceProcessor>(
     135           0 :           std::make_shared<UserTimelineHandler>(
     136             :               &redis_replica_client_pool, &redis_primary_client_pool, mongodb_client_pool,
     137             :               &post_storage_client_pool)),
     138             :           server_socket,
     139           0 :           std::make_shared<TFramedTransportFactory>(),
     140           0 :           std::make_shared<TBinaryProtocolFactory>());
     141           0 :       LOG(info) << "Starting the user-timeline-service server with replicated Redis support...";
     142           0 :       server.serve();
     143             : 
     144             :   }
     145             :   else {
     146             :     Redis redis_client_pool =
     147           1 :         init_redis_client_pool(config_json, "user-timeline");
     148           2 :     TThreadedServer server(std::make_shared<UserTimelineServiceProcessor>(
     149           2 :                                std::make_shared<UserTimelineHandler>(
     150             :                                    &redis_client_pool, mongodb_client_pool,
     151             :                                    &post_storage_client_pool)),
     152             :                            server_socket,
     153           2 :                            std::make_shared<TFramedTransportFactory>(),
     154           6 :                            std::make_shared<TBinaryProtocolFactory>());
     155           2 :     LOG(info) << "Starting the user-timeline-service server...";
     156           1 :     server.serve();
     157             :   }
     158           3 : }

Generated by: LCOV version 1.12