File: preforked-server.hpp

package info (click to toggle)
libzeep 5.1.8-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 3,596 kB
  • sloc: cpp: 27,393; xml: 7,798; javascript: 180; sh: 37; makefile: 8
file content (88 lines) | stat: -rw-r--r-- 2,793 bytes parent folder | download
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
// Copyright Maarten L. Hekkelman, Radboud University 2008-2013.
//        Copyright Maarten L. Hekkelman, 2014-2022
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#pragma once

/// \file
/// Code for a preforked http server implementation

#include <zeep/config.hpp>

#include <zeep/http/server.hpp>

#if HTTP_SERVER_HAS_PREFORK

namespace zeep::http
{

/// \brief class to create a preforked HTTP server
///
/// A preforked server means you have a master process that listens to a port
/// and whenever a request comes in, the socket is passed to a client. This
/// client will then process the request.
/// This approach has several advantages related to security and stability.
///
/// The way it works in libzeep is, you still create a server that derives
/// from zeep::server (if you need a SOAP server) or zeep::http::server (if
/// you only want a HTTP server). You then create a
/// zeep::http::preforked_server<YourServer> instance passing in the
/// parameters required and then call run() on this preforked server.
///
///	The preforked_server class records the way your server needs to be
/// constructed. When this preforked_server is run, it forks and then
/// constructs your server class in the child process.
///
/// Example:
/// \code{.cpp}
///		class my_server {
///     public:
///		  my_server(const string& my_param);
///
///		....
///
///		zeep::http::preforked_server<my_server> server(
///         []() { return new my_server("my param value"); }
///     );
///
///     // all addresses, port 10333 and two listener threads
///		std::thread t(std::bind(&zeep::http::preforked_server::run, &server, "0.0.0.0", 10333, 2));
///
///		... // wait for signal to stop
///     
///		server.stop();
///		t.join();
/// \endcode

class child_process;

class preforked_server
{
  public:
    preforked_server(const preforked_server&) = delete;
    preforked_server& operator=(const preforked_server&) = delete;

    /// \brief constructor
    ///
    /// The constructor takes one argument, a function object that creates 
    /// a server class instance.
    preforked_server(std::function<basic_server*(void)> server_factory);
    virtual ~preforked_server();

    /// \brief forks \a nr_of_child_processes children and starts listening, should be a separate thread
    virtual void run(const std::string& address, short port, int nr_of_child_processes, int nr_of_threads);
    virtual void start();			///< signal the thread it can start listening:
    virtual void stop();			///< stop the running thread

  private:

    std::function<basic_server*(void)>	m_constructor;
    std::mutex						m_lock;
	boost::asio::io_context			m_io_context;
};

}

#endif