-
Notifications
You must be signed in to change notification settings - Fork 758
Deterministic way to know if server has started #176
Comments
I have a piece of code that may help you. Not exactly what you are asking for, but you certanly can extend it to your personal needs. Note:
Edit: |
Thanks for the suggestion. I understand the technique you describe, but it addresses a different aspect of the problem. Because the start() method doesn't exit until the server has been stopped, the catch statement in your example will catch exceptions during server start-up, and also exceptions while the server is running (e.g. due to a bug or resoure limitations). That's fine, but if I want to block the calling thread until the server has successfully started I have no way of knowing how long I should wait for except for guessing a maximum amount of time that the server might need to start. There are two reasons for an application to know the difference between a server that is running and one that is still starting up:
|
Wow, I just realized we have the same problem. |
I did a quick implementation here: #include "server_http.hpp"
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
int main() {
HttpServer server;
server.config.port = 8080;
std::thread server_thread([&server] {
server.start();
});
{
// Wait till server is started
while(!server.io_service)
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::condition_variable cv;
std::mutex cv_mutex;
server.io_service->post([&cv, &cv_mutex] {
std::unique_lock<std::mutex> lock(cv_mutex);
cv.notify_one();
});
std::unique_lock<std::mutex> lock(cv_mutex);
cv.wait(lock);
std::cout << "Server is now accepting requests" << std::endl;
}
server_thread.join();
} I'm not very fond of the while-loop, but that can be fixed by using an external io_service: #include "server_http.hpp"
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
int main() {
HttpServer server;
server.config.port = 8080;
server.io_service = std::make_shared<SimpleWeb::asio::io_service>();
std::thread server_thread([&server] {
server.start();
server.io_service->run();
});
{
// Wait till server is started
std::condition_variable cv;
std::mutex cv_mutex;
server.io_service->post([&cv, &cv_mutex] {
std::unique_lock<std::mutex> lock(cv_mutex);
cv.notify_one();
});
std::unique_lock<std::mutex> lock(cv_mutex);
cv.wait(lock);
std::cout << "Server is now accepting requests" << std::endl;
}
server_thread.join();
} In both examples above, I post a task to the io_service, and when this task has been performed I know that the server's io_service is up and running and is accepting tasks through async_accept call. |
Thanks - that addresses the problem! Would it be sensible to add some code similar to that to the library as a testIfServerIsRunning() type method? |
How do i unsubscribe for this, so annoying.
Rgds
Sashidhar Rathod
[email protected]
+917353043601
…On Wed, Nov 29, 2017 at 8:56 PM, Vitor Alves ***@***.***> wrote:
I have a piece of code that may help you. Not exactly what you are asking
for, but you certanly can extend it to your personal needs.
One option for you would be to catch an exception on server.start()
inside the thread and pass this information to the parent thread. My code
only catches the exception and logs it, but modifying it to pass this
information to the parent is not hard.
Note: HttpServer server is defined outside the lambda and passed by
reference
void RestAPI::start_server() {
server_thread = std::make_unique<std::thread>( [&]() {
try {
server.start();
LOG_INFO << "Web UI and REST API server have been started and are listening on "
<< server.config.address << ":" << server.config.port;
}
catch(std::exception const &e) {
LOG_ERROR << "Web server error: " << e.what() << ". Is port " <<
server.config.port << " already in use?" ;
std::cerr << "Web server error: " << e.what() << ". Is port " <<
server.config.port << " already in use?"
<< " Check log files for more information." << std::endl;
}} );
server.on_error = [](std::shared_ptr<HttpServer::Request> request, const SimpleWeb::error_code & ec) {
LOG_ERROR << "Web server error: " << ec.message();
};
}
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#176 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AY1M8vuepoJgrhq_ZimEukEKz1xgrPzXks5s7XezgaJpZM4QvGj3>
.
|
click the unsubscribe button in the right |
On Dec 1, 2017, at 5:57 AM, Shashirathod7 ***@***.***> wrote:
How do i unsubscribe for this, so annoying.
This is from GitHub, so you can use all of the standard GitHub ways of deciding what you want to listed to.
At the bottom of the email, GitHub supplies two links. The first one can be used to unsubscribe from all of Simple-Web-Server: go to the top of the page and click “Unwatch”. The second link can be used to unsubscribe from *this particular conversation* (i.e. Deterministic way to know if server has started).
|
I think there is a synchronization issue in suggested code: |
@jschrotter you are right. This is hopefully a better solution: #include "server_http.hpp"
using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>;
int main() {
HttpServer server;
server.config.port = 8080;
server.io_service = std::make_shared<SimpleWeb::asio::io_service>();
std::thread server_thread([&server] {
server.start();
server.io_service->run();
});
std::promise<void> started;
server.io_service->post([&started] {
started.set_value();
});
started.get_future().get();
std::cout << "Server is now accepting requests" << std::endl;
server_thread.join();
} |
Hi,
Is there a deterministic way to know from the parent thread if the server has started successfully? In the example application it just calls the start method and waits for a second and then assumes the server is running. But, I guess it is possible that the server start-up may take more than a second (e.g. on a machine that has very high CPU occupancy).
I am particularly thinking of how best to detect from the parent thread exceptions in the server thread (such as port conflicts) that prevent the server starting successfully.
With thanks for a great tool.
Iain
The text was updated successfully, but these errors were encountered: