From 919fa54a98514ae98c2a3c1b2bc47ef118fd92a8 Mon Sep 17 00:00:00 2001 From: Adam Gu Date: Thu, 12 Apr 2018 09:21:04 +0800 Subject: [PATCH] Refine the draft timeout control from server side. --- example/rest_book_server/book_services.cc | 9 ---- example/rest_book_server/main.cc | 5 -- src/webcc/http_server.cc | 5 +- src/webcc/http_server.h | 8 --- src/webcc/http_session.cc | 62 ++++------------------- src/webcc/http_session.h | 11 +--- 6 files changed, 12 insertions(+), 88 deletions(-) diff --git a/example/rest_book_server/book_services.cc b/example/rest_book_server/book_services.cc index 551e66d..b068650 100644 --- a/example/rest_book_server/book_services.cc +++ b/example/rest_book_server/book_services.cc @@ -3,8 +3,6 @@ #include #include "boost/lexical_cast.hpp" -#include "boost/thread.hpp" -#include "boost/date_time/posix_time/posix_time.hpp" //////////////////////////////////////////////////////////////////////////////// @@ -115,10 +113,6 @@ bool BookListService::Handle(const std::string& http_method, std::string* response_content) { if (http_method == webcc::kHttpGet) { *response_content = CreateBookListJson(g_book_store.books()); - - // Sleep for testing timeout control. - //boost::this_thread::sleep(boost::posix_time::seconds(2)); - return true; } @@ -146,9 +140,6 @@ bool BookDetailService::Handle(const std::string& http_method, *response_content = CreateBookJson(book); - // Sleep for testing timeout control. - //boost::this_thread::sleep(boost::posix_time::seconds(2)); - return true; } else if (http_method == webcc::kHttpPost) { diff --git a/example/rest_book_server/main.cc b/example/rest_book_server/main.cc index 3d540dc..937f1f7 100644 --- a/example/rest_book_server/main.cc +++ b/example/rest_book_server/main.cc @@ -27,11 +27,6 @@ int main(int argc, char* argv[]) { server.RegisterService(std::make_shared(), "/books/(\\d+)"); - // For test purpose. - // Timeout like 60s makes more sense in a real product. - // Leave it as default (0) for no timeout control. - server.set_timeout_seconds(1); - server.Run(); } catch (std::exception& e) { diff --git a/src/webcc/http_server.cc b/src/webcc/http_server.cc index 56c29d4..86e50d9 100644 --- a/src/webcc/http_server.cc +++ b/src/webcc/http_server.cc @@ -16,8 +16,7 @@ namespace webcc { HttpServer::HttpServer(unsigned short port, std::size_t workers) : signals_(io_context_) - , workers_(workers) - , timeout_seconds_(0) { + , workers_(workers) { // Register to handle the signals that indicate when the server should exit. // It is safe to register for the same signal multiple times in a program, @@ -78,7 +77,7 @@ void HttpServer::DoAccept() { HttpSessionPtr session{ new HttpSession(std::move(socket), GetRequestHandler()) }; - session->Start(timeout_seconds_); + session->Start(); } DoAccept(); diff --git a/src/webcc/http_server.h b/src/webcc/http_server.h index a78c827..098897c 100644 --- a/src/webcc/http_server.h +++ b/src/webcc/http_server.h @@ -28,10 +28,6 @@ public: virtual ~HttpServer(); - void set_timeout_seconds(long seconds) { - timeout_seconds_ = seconds; - } - // Run the server's io_service loop. void Run(); @@ -57,10 +53,6 @@ private: // Acceptor used to listen for incoming connections. boost::scoped_ptr acceptor_; - - // Timeout in seconds for socket connection. - // Default is 0 which means no timeout. - long timeout_seconds_; }; } // namespace webcc diff --git a/src/webcc/http_session.cc b/src/webcc/http_session.cc index d81f5cd..7756d8e 100644 --- a/src/webcc/http_session.cc +++ b/src/webcc/http_session.cc @@ -22,27 +22,13 @@ HttpSession::HttpSession(boost::asio::ip::tcp::socket socket, HttpSession::~HttpSession() { } -void HttpSession::Start(long timeout_seconds) { - if (timeout_seconds > 0) { - // Create timer only necessary. - boost::asio::io_context& ioc = socket_.get_executor().context(); - timer_.reset(new boost::asio::deadline_timer(ioc)); - - timer_->expires_from_now(boost::posix_time::seconds(timeout_seconds)); - - timer_->async_wait(std::bind(&HttpSession::HandleTimer, - shared_from_this(), - std::placeholders::_1)); - } - +void HttpSession::Start() { DoRead(); } void HttpSession::Stop() { - CancelTimer(); - - boost::system::error_code ignored_ec; - socket_.close(ignored_ec); + boost::system::error_code ec; + socket_.close(ec); } void HttpSession::SetResponseContent(const std::string& content_type, @@ -78,8 +64,6 @@ void HttpSession::HandleRead(boost::system::error_code ec, if (ec) { if (ec != boost::asio::error::operation_aborted) { Stop(); - } else { - CancelTimer(); } return; } @@ -116,53 +100,25 @@ void HttpSession::HandleWrite(boost::system::error_code ec, #endif if (!ec) { - CancelTimer(); +#if WEBCC_DEBUG_OUTPUT + std::cout << "Response has been sent back (thread: " << thread_id << ")\n"; +#endif // Initiate graceful connection closure. boost::system::error_code ec; socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); -#if WEBCC_DEBUG_OUTPUT - std::cout << "Response has been sent back (thread: " << thread_id << ")\n"; -#endif } else { #if WEBCC_DEBUG_OUTPUT std::cout << "(thread: " << thread_id << ") Sending response error: " - << ec.message() - << std::endl; + << ec.message() + << std::endl; #endif - if (ec == boost::asio::error::operation_aborted) { - CancelTimer(); - } else { + if (ec != boost::asio::error::operation_aborted) { Stop(); } } } -void HttpSession::HandleTimer(boost::system::error_code ec) { - std::cout << "HandleTimer: "; - - if (!ec) { - if (socket_.is_open()) { - std::cout << "socket is open, close it.\n"; - socket_.close(); - } else { - std::cout << "socket is not open.\n"; - } - } else { - if (ec == boost::asio::error::operation_aborted) { - std::cout << "Timer aborted\n"; - } - } -} - -void HttpSession::CancelTimer() { - if (timer_) { - // The wait handler will be invoked with the operation_aborted error code. - boost::system::error_code ec; - timer_->cancel(ec); - } -} - } // namespace webcc diff --git a/src/webcc/http_session.h b/src/webcc/http_session.h index a94460b..296913f 100644 --- a/src/webcc/http_session.h +++ b/src/webcc/http_session.h @@ -5,7 +5,6 @@ #include #include "boost/asio/ip/tcp.hpp" // for ip::tcp::socket -#include "boost/asio/deadline_timer.hpp" #include "webcc/common.h" #include "webcc/http_request.h" @@ -30,8 +29,7 @@ public: return request_; } - // Start the session with an optional timeout. - void Start(long timeout_seconds = 0); + void Start(); void Stop(); @@ -54,17 +52,10 @@ private: void HandleRead(boost::system::error_code ec, std::size_t length); void HandleWrite(boost::system::error_code ec, std::size_t length); - void HandleTimer(boost::system::error_code ec); - - void CancelTimer(); - private: // Socket for the connection. boost::asio::ip::tcp::socket socket_; - // Timeout timer (optional). - std::unique_ptr timer_; - // The handler used to process the incoming request. HttpRequestHandler* request_handler_;