meltwater / served

A C++11 RESTful web server library
MIT License
710 stars 174 forks source link

Configure blocking nature for server run #42

Closed luismartingil closed 5 years ago

luismartingil commented 5 years ago

Hi @Jeffail

All the examples are implemented using a blocking run call.

served::multiplexer mux;
...
served::net::server server("127.0.0.1", "8123", mux);
server.run(10);

I was wondering if you have any suggestion on how to bind and start serving without a blocking call. Similar to:

served::multiplexer mux;
...
served::net::server server("127.0.0.1", "8123", mux);
server.start(10); // maybe do_accept?
// Do other stuff
server.stop();

May I just focus on running this in another thread?

I can maybe look deeper to boost io_service but wanted to have your thoughts first.

Congrats for such a great lib! Luis

luismartingil commented 5 years ago

@Jeffail

Please see this PR https://github.com/meltwater/served/pull/43

What do you think?

luismartingil commented 5 years ago

@jpihl Do you know who is the maintainer of this library? Thanks

jpihl commented 5 years ago

Hi @luismartingil,

I think Jeffail is the maintainer. If you want to run the server in a different thread you can do like this:

#include <thread>
...
served::multiplexer mux;
served::net::server server("127.0.0.1", "8123", mux);
std::thread t([server](){ server.run(10); });
...
server.stop();
t.join();
Jeffail commented 5 years ago

Hey @luismartingil, sorry for the late response, I've been travelling. The solution @jpihl suggested is what I'd recommend for the short term. The only thing to be aware of is that SIGINT and SIGTERM are captured here: https://github.com/meltwater/served/blob/master/src/served/net/server.cpp#L51, which obviously ruins your day if you needed to capture those in your own main block.

Your pull request is a good start for a proper solution, but we should also make the signal captures either a flag themselves or at least dependent on whether run is being called in a blocking way.

jpihl commented 5 years ago

Yes I forgot about that. I handle this with the following (simplified) code. It's a bit cumbersome though so it would be nice with a different approach.

boost::asio::io_service io;
boost::asio::signal_set signal_set(io,  SIGINT, SIGTERM);
signals.async_wait([&server, &t, &io](auto error, auto signal_number) {
    if (error)
        return;
    server.stop();
    t.join();
    io.stop();
});
luismartingil commented 5 years ago

Thanks for the responses!

@jpihl That was my original approach, just wondering if we could have the served library to provide this functionality. Thanks anyway for the insight and contribution.

@Jeffail I'll look into that and update the PR.

luismartingil commented 5 years ago

@Jeffail,

PR #43 was updated:

Please let me know what you think. I'm interested in this being included in the library if possible.

Thanks!

Jeffail commented 5 years ago

@luismartingil looks great, thanks!