aboutsummaryrefslogtreecommitdiffstats
path: root/slobrok/src/apps/slobrok/slobrok.cpp
blob: 43a2f84feb4245035639041073a1c8249a24af96 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include <vespa/slobrok/server/sbenv.h>
#include <vespa/config/common/exceptions.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/util/signalhandler.h>
#include <csignal>
#include <unistd.h>

#include <vespa/log/log.h>
LOG_SETUP("vespa-slobrok");

/**
 * @brief namespace for the actual slobrok application.
 **/
namespace slobrok {

class App
{
public:
    int main(int argc, char **argv);
};

static std::unique_ptr<SBEnv> mainobj;

extern "C" {
static void sigtermhandler(int signo);
};

static void
sigtermhandler(int signo)
{
    (void) signo;
    if (mainobj) {
        mainobj->shutdown();
    }
}

static void
hook_sigterm(void)
{
    struct sigaction act;
    act.sa_handler = sigtermhandler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    sigaction(SIGTERM, &act, NULL);
}


int
App::main(int argc, char **argv)
{
    uint32_t portnum = 2773;
    vespalib::string cfgId;

    int c;
    while ((c = getopt(argc, argv, "c:s:p:N")) != -1) {
        switch (c) {
        case 'c':
            cfgId = std::string(optarg);
            break;
        case 'p':
            portnum = atoi(optarg);
            break;
        case 'N':
            // ignored
            break;
        default:
            LOG(error, "unknown option letter '%c'", c);
            return 1;
        }
    }
    int res = 1;
    try {
        if (cfgId.empty()) {
            LOG(debug, "no config id specified");
            ConfigShim shim(portnum);
            mainobj = std::make_unique<SBEnv>(shim);
        } else {
            ConfigShim shim(portnum, cfgId);
            shim.enableStateServer(true);
            mainobj = std::make_unique<SBEnv>(shim);
        }
        hook_sigterm();
        res = mainobj->MainLoop();
    } catch (const config::ConfigTimeoutException &e) {
        LOG(error, "config timeout during construction : %s", e.what());
        EV_STOPPING("slobrok", "config timeout during construction");
        res = 1;
    } catch (const vespalib::PortListenException &e) {
        LOG(error, "Failed listening to network port(%d) with protocol(%s): '%s'",
                   e.get_port(), e.get_protocol().c_str(), e.what());
        EV_STOPPING("slobrok", "could not listen to our network port");
        res = 1;
    } catch (const std::exception & e) {
        LOG(error, "unknown exception during construction : %s", e.what());
        EV_STOPPING("slobrok", "unknown exception during construction");
        res = 2;
    }
    if (mainobj && !mainobj->isShuttingDown()) {
        mainobj->shutdown();
    }
    mainobj.reset();
    return res;
}

} // namespace slobrok

int main(int argc, char **argv) {
    vespalib::SignalHandler::PIPE.ignore();
    slobrok::App slobrok;
    return slobrok.main(argc, argv);
}