aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/monlib/service/service.h
blob: 6aa112902e6e32ccaff9ef94941471543311cebc (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
#pragma once

#include <library/cpp/coroutine/engine/impl.h>
#include <library/cpp/coroutine/listener/listen.h>
#include <library/cpp/http/fetch/httpheader.h>
#include <library/cpp/http/server/http.h>
#include <library/cpp/logger/all.h>

#include <util/network/ip.h>
#include <library/cpp/cgiparam/cgiparam.h>

#include <functional>

struct TMonitor;

namespace NMonitoring {
    struct IHttpRequest {
        virtual ~IHttpRequest() {
        }
        virtual const char* GetURI() const = 0;
        virtual const char* GetPath() const = 0;
        virtual const TCgiParameters& GetParams() const = 0;
        virtual const TCgiParameters& GetPostParams() const = 0;
        virtual TStringBuf GetPostContent() const = 0;
        virtual HTTP_METHOD GetMethod() const = 0;
        virtual const THttpHeaders& GetHeaders() const = 0;
        virtual TString GetRemoteAddr() const = 0;
    };
    // first param - output stream to write result to
    // second param - URL of request
    typedef std::function<void(IOutputStream&, const IHttpRequest&)> THandler;

    class TCoHttpServer: private TContListener::ICallBack {
    public:
        // initialize and schedule coroutines for execution
        TCoHttpServer(TContExecutor& executor, const TString& bindAddr, TIpPort port, THandler handler);
        void Start();
        void Stop();

        // this function implements THandler interface
        // by forwarding it to the httpserver
        // @note this call may be blocking; don't use inside coroutines
        // @throws may throw in case of connection error, etc
        void ProcessRequest(IOutputStream&, const IHttpRequest&); 

    private:
        class TConnection;

        // ICallBack implementation
        void OnAcceptFull(const TAcceptFull& a) override;
        void OnError() override;

    private:
        TContExecutor& Executor;
        TContListener Listener;
        THandler Handler;
        TString BindAddr;
        TIpPort Port;
    };

    class TMtHttpServer: public THttpServer, private THttpServer::ICallBack {
    public:
        TMtHttpServer(const TOptions& options, THandler handler, IThreadFactory* pool = nullptr);
        TMtHttpServer(const TOptions& options, THandler handler, TSimpleSharedPtr<IThreadPool> pool);

        /**
         * This will cause the server start to accept incoming connections.
         *
         * @return true if the port binding was successfull,
         *         false otherwise.
         */
        bool Start();

        /**
         * Same as Start() member-function, but will throw TSystemError if
         * there were some errors.
         */
        void StartOrThrow();

        /**
         * Stops the server from accepting new connections.
         */
        void Stop();

    private:
        class TConnection;
        TClientRequest* CreateClient() override;

        THandler Handler;
    };

    // this class implements hybrid coroutine and threaded approach
    // requests for main page which holds counters and simple tables are served in a thread
    // requests for other pages which include access with inter-thread synchonization
    // will be served in a coroutine context
    class TMonService {
    public:
        TMonService(TContExecutor& executor, TIpPort internalPort, TIpPort externalPort,
                    THandler coHandler, THandler mtHandler);
        void Start();
        void Stop();

    protected:
        void DispatchRequest(IOutputStream& out, const IHttpRequest&); 

    private:
        TCoHttpServer CoServer;
        TMtHttpServer MtServer;
        THandler MtHandler;
    };

}