Using restinio::run

Simple forms of restinio::run

The simplest way of running RESTinio server is the usage of restinio::run functions. For example, to run single-threaded RESTinio server on the context of the current thread:

restinio::run(
  restinio::on_this_thread()
    .port(8080)
    .address("localhost")
    .request_handler([](auto req) {
      return req->create_response().set_body("Hello, World!").done();
    }));
// The current thread will be blocked until RESTinio server finishes its work.

To run multi-threaded RESTinio server on the context of thread pool:

restinio::run(
  restinio::on_thread_pool(16) // Thread pool size is 16 threads.
    .port(8080)
    .address("localhost")
    .request_handler([](auto req) {
      return req->create_response().set_body("Hello, World!").done();
    }));
// The current thread will be blocked until RESTinio server finishes its work.

Note that run() doesn’t provide a way to stop the server from outside of run(). It means that run() will block the current thread until the server will finish its work by itself. However inside run() a signal handler for SIGINT it installed and the server finishes its work when SIGINT is sent to the application (for example if the user breaks the application by pressing Ctrl+C/Ctrl+Break). Such approach seems to be appropriate for very simple servers like small test programs or quick-and-dirty prototypes. If you need more control you should use restinio::run_async function or restinio::http_server_t class.

A user-defined traits for RESTinio server can be passed as template parameters for restinio::on_this_thread and restinio::on_thread_pool helpers. For example:

using my_traits_t = restinio::traits_t<
    restinio::asio_timer_manager_t,
    restinio::single_threaded_ostream_logger_t,
    restinio::router::express_router_t >;
restinio::run(
  restinio::on_this_thread<my_traits_t>()
    .port(8080)
    .address("localhost")
    .request_handler([](auto req) {
      return req->create_response().set_body("Hello, World!").done();
    }));
// The current thread will be blocked until RESTinio server finishes its work.

Version of restinio::run for an existing http_server_t object

Since v.0.5.1 there is another version of restinio::run function that can be used for an existing http_server_t object. This form can be used in case when an access to http_server_t is necessary from some worker thread. For example:

// Create server instance on the main thread.
using my_server_t = restinio::http_server_t< my_server_traits_t >;
my_server_t server{
   restinio::own_io_context(),
   [](auto & settings) {
      settings.port(...);
      settings.address(...);
      settings.request_handler(...);
      ...
   }
};
// Create a separate thread to control execution of RESTinio's server.
std::thread restinio_control_thread{ [&server] {
      // Use restinio::run to launch RESTinio's server.
      // This run() will return only if server stopped from
      // some other thread.
      restinio::run( restinio::on_thread_pool(
            4, // Count of worker threads for RESTinio.
            restinio::skip_break_signal_handling(), // Don't react to Ctrl+C.
            server) // Server to be run.
         );
   }
};
... // Some application-dependent logic there. Maybe creation of
   // some GUI windows.

// Now RESTinio can be stopped.
restinio::initiate_shutdown(server);
// Wait for completeness of RESTinio's shutdown.
restinio_control_thread.join();

NOTE. There is only restinio::run(restinio::on_thread_pool()) form for running RESTinio with already existing http_server_t instance. If you need some other form of restinio::run please open an issue on GitHub.

run_async function

A helper function restinio::run_async was introduced in v.0.6.7. It allows to run an instance of RESTinio’s server on a separate thread or thread pool. For example:

int main() {
   auto server = restinio::run_async(
      // Asio's io_context to be used.
      // HTTP-server will use own Asio's io_context object.
      restinio::own_io_context(),
      // The settings for the HTTP-server.
      restinio::server_settings_t{}
         .address("127.0.0.1")
         .port(8080)
         .request_handler(...),
      // The size of thread-pool for the HTTP-server.
      16);
   // If we are here and run_async doesn't throw then HTTP-server
   // is started.

   ... // Some other actions.

   // No need to stop HTTP-server manually. It will be automatically
   // stopped in the destructor of `server` object.
}

The run_async returns control when HTTP-server is started or some startup failure is detected. But if a failure is detected then an exception is thrown. So if run_async returns successfuly then HTTP-server is working.

The run_async function returns an instance of restinio::running_service_instance_t<Http_Server> class that can be used for controlling a work of started HTTP-server:

auto server = restinio::run_async(...);

... // Some application specific logic.

// Initiate a shutdown of HTTP-server.
server.stop();

... // Some other application specific actions.

// Wait until HTTP-server finishes its work.
server.wait();

Please note that there is no need to call stop() and wait() methods manually, they will automatically be called by the destructor of running_service_instance_t.

A server to be run asynchronously can be parametrized by custom user-defined traits:

struct my_traits : public restinio::default_traits_t {
   ...
};

auto server = restinio::run_async<my_traits>(
   restinio::own_io_context(),
   restinio::server_settings_t<my_traits>{}
      .address(...)
      .port(...)
      .request_handler(...),
   16u);

NOTE. The function run_async doesn’t install handlers for Ctrl+C/SIGINT signals.

A helper class on_pool_runner_t

Sometimes it is necessary to run http_server_t on a thread pool but without the creation of separate control thread like in the example shown above. In that case a helper class on_pool_runner_t can be used:

// HTTP-server to be run on a thread pool.
restinio::http_server_t< my_traits > server{...};

// Launch HTTP-server on a thread pool.
restinio::on_pool_runner_t< restinio::http_server_t<my_traits> > runner{
      16,
      server
};

... // Some application specific code here.

// Now the server can be stopped.
runner.stop(); // (1)
runner.wait();

NOTE. A manual call to stop() and wait() methods as shown in the point (1) is not necessary: the destructor of on_pool_runner_t will call them automatically if the HTTP-server is not stopped yet.

NOTE. Class on_pool_runner_t doesn’t install handlers for Ctrl+C/SIGINT signals.