From fd5d218e8e7df49c1b1fec72cf69fc445855c206 Mon Sep 17 00:00:00 2001 From: Stephen Chen Date: Mon, 1 Jul 2013 19:39:17 -0700 Subject: [PATCH] HPHP: Drop the request when it's been sitting on the select queue longer than the virtual host timeout allows for. Drop the request when it's been sitting on the select queue longer than the virtual host timeout allows for. This is orthogonal to the expiration timeout on the queue itself. This can be useful if we ever allow select queue timeout to be configured to be higher than the virtual host request timeout. --- .../base/server/http_request_handler.cpp | 24 ++++++++++++++++++- .../base/server/http_request_handler.h | 6 +++++ hphp/runtime/base/server/virtual_host.cpp | 4 ++++ hphp/runtime/base/server/virtual_host.h | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/hphp/runtime/base/server/http_request_handler.cpp b/hphp/runtime/base/server/http_request_handler.cpp index 2a261a721..3333ee96a 100644 --- a/hphp/runtime/base/server/http_request_handler.cpp +++ b/hphp/runtime/base/server/http_request_handler.cpp @@ -32,6 +32,7 @@ #include "hphp/runtime/base/time/datetime.h" #include "hphp/runtime/debugger/debugger.h" #include "hphp/util/alloc.h" +#include "hphp/util/service_data.h" namespace HPHP { /////////////////////////////////////////////////////////////////////////////// @@ -43,7 +44,10 @@ AccessLog HttpRequestHandler::s_accessLog( &(HttpRequestHandler::getAccessLogThreadData)); HttpRequestHandler::HttpRequestHandler() - : m_pathTranslation(true) { + : m_pathTranslation(true), + m_requestTimedOutOnQueue(ServiceData::createTimeseries( + "requests_timed_out_on_queue", + {ServiceData::StatsType::COUNT})) { } void HttpRequestHandler::sendStaticContent(Transport *transport, @@ -129,6 +133,24 @@ void HttpRequestHandler::handleRequest(Transport *transport) { transport->sendString("Not Found", 404); return; } + + // don't serve the request if it's been sitting in queue for longer than our + // allowed request timeout. + int requestTimeoutSeconds = (vhost->getRequestTimeoutSeconds() > 0 ? + vhost->getRequestTimeoutSeconds() : + RuntimeOption::RequestTimeoutSeconds); + if (requestTimeoutSeconds > 0) { + timespec now; + gettime(CLOCK_MONOTONIC, &now); + const timespec& queueTime = transport->getQueueTime(); + + if (gettime_diff_us(queueTime, now) > requestTimeoutSeconds * 1000000) { + transport->sendString("Service Unavailable", 503); + m_requestTimedOutOnQueue->addValue(1); + return; + } + } + ServerStats::StartRequest(transport->getCommand().c_str(), transport->getRemoteHost(), vhost->getName().c_str()); diff --git a/hphp/runtime/base/server/http_request_handler.h b/hphp/runtime/base/server/http_request_handler.h index 82853d96d..dd9bff385 100644 --- a/hphp/runtime/base/server/http_request_handler.h +++ b/hphp/runtime/base/server/http_request_handler.h @@ -26,6 +26,11 @@ namespace HPHP { class SourceRootInfo; class RequestURI; + +namespace ServiceData { +class ExportedTimeSeries; +} + /////////////////////////////////////////////////////////////////////////////// class HttpRequestHandler : public RequestHandler { @@ -43,6 +48,7 @@ public: private: bool m_pathTranslation; + ServiceData::ExportedTimeSeries* m_requestTimedOutOnQueue; bool handleProxyRequest(Transport *transport, bool force); void sendStaticContent(Transport *transport, const char *data, int len, diff --git a/hphp/runtime/base/server/virtual_host.cpp b/hphp/runtime/base/server/virtual_host.cpp index 252a7c1ec..d6728c837 100644 --- a/hphp/runtime/base/server/virtual_host.cpp +++ b/hphp/runtime/base/server/virtual_host.cpp @@ -136,6 +136,10 @@ void VirtualHost::setRequestTimeoutSeconds() const { } } +int VirtualHost::getRequestTimeoutSeconds() const { + return m_runtimeOption.requestTimeoutSeconds; +} + VirtualHost::VirtualHost() : m_disabled(false) { Hdf empty; initRuntimeOption(empty); diff --git a/hphp/runtime/base/server/virtual_host.h b/hphp/runtime/base/server/virtual_host.h index 23be7dae2..645640600 100644 --- a/hphp/runtime/base/server/virtual_host.h +++ b/hphp/runtime/base/server/virtual_host.h @@ -42,6 +42,7 @@ public: void init(Hdf vh); void addAllowedDirectories(const std::vector& dirs); void setRequestTimeoutSeconds() const; + int getRequestTimeoutSeconds() const; const std::string &getName() const { return m_name;} const std::string &getPathTranslation() const { return m_pathTranslation;}