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 : }
|