Add proper per-file copyright notices/licenses and top-level license.
[bluesky.git] / kvstore / kvstore.cc
1 #include <boost/program_options.hpp>
2 #include <boost/shared_ptr.hpp>
3 #include <iostream>
4 #include <string>
5 #include <ctime>
6 #include <csignal>
7 #include "kvservice.h"
8 #include "protobufrpc.h"
9
10 using namespace bicker;
11 using namespace boost;
12 using namespace kvstore;
13 using namespace std;
14
15 namespace po = boost::program_options;
16
17 int interrupted_count = 0;
18 ProtoBufRpcServer rpc_server;
19
20 void
21 interrupted(int /*signal*/)
22 {
23     if (interrupted_count < 1)
24     {
25         rpc_server.shutdown();
26     }
27     else
28     {
29         exit(1);
30     }
31     ++interrupted_count;
32 }
33
34 int
35 main(
36      int argc,
37      char **argv
38     )
39 {
40     shared_ptr<thread> server_thread;
41
42     /* Initialize Exception Handling */
43     struct sigaction action;
44
45     action.sa_handler = &interrupted;
46     action.sa_flags = SA_SIGINFO;
47     sigemptyset(&action.sa_mask);
48
49     if (sigaction(SIGINT, &action, NULL) == -1)
50     {
51         perror("sigaction");
52         exit(1);
53     }
54
55     /* Parse Options */
56     string opt_bdb_home;
57     uint16_t opt_port;
58     uint16_t opt_sleep;
59
60     po::options_description options("Options");
61
62     options.add_options()
63         ("help,h", "display help message")
64         ("bdb-home,d",
65          po::value< vector<string> >(),
66          "bdb home directories")
67         ("port",
68          po::value<uint16_t>(&opt_port)->default_value(9090),
69          "listen port")
70         ("foreground,f", "don't fork to the background")
71         ("sleep,s", po::value<uint16_t>(&opt_sleep)->default_value(0), "sleep then exit")
72         ;
73
74     po::variables_map vm;
75     po::store(po::parse_command_line(argc, argv, options), vm);
76     po::notify(vm);
77
78     if (vm.count("help"))
79     {
80         cerr << options << endl;
81         return 1;
82     }
83
84
85     vector<string> paths;
86
87     if (vm.count("bdb-home") > 0)
88     {
89         paths = vm["bdb-home"].as< vector<string> >();
90     }
91     else
92     {
93         paths.push_back("./");
94     }
95
96
97     shared_ptr<Service> service(new KeyValueRpcService(new BDBBackend(paths)));
98
99     rpc_server.registerService(opt_port, service);
100
101     server_thread.reset(
102                          new thread(
103                                     boost::bind(
104                                                 &ProtoBufRpcServer::run, 
105                                                 &rpc_server)));
106
107     if (!vm.count("foreground"))
108     {
109         // Daemonize
110         if (daemon(0,0) != 0)
111         {
112             perror("daemonizing");
113             exit(1);
114         }
115     }
116
117     if (opt_sleep == 0)
118     {
119         server_thread->join();
120     }
121     else
122     {
123         time_t t0 = time(NULL);
124         time_t t1;
125
126         do
127         {
128             t1 = time(NULL);
129             sleep(opt_sleep - (t1 - t0));
130         } while (t1 - t0 < opt_sleep);
131     }
132     rpc_server.shutdown();
133
134     return 0;
135 }
136
137