Build-time configurable WSD limits

The server can now be configured at build time
to limit the total number of connections and/or
the number of open documents, at a given time.

./configure --with-max-documents=10 --with-max-connections=20
will limit the number of documents to 10 and total
number of connections (on one or all documents) to 20.

Change-Id: I0c73a7e906c4f567cb3da480e885524815c9cc89
Reviewed-on: https://gerrit.libreoffice.org/27203
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
private/Ashod/repairactions
Ashod Nakashian 2016-07-13 22:01:23 -04:00 committed by Ashod Nakashian
parent 0f506fcbb0
commit f52fa89036
4 changed files with 64 additions and 0 deletions

View File

@ -594,6 +594,15 @@ private:
throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_INTERNAL_ERROR);
}
#if MAX_DOCUMENTS > 0
if (++LOOLWSD::NumDocBrokers > MAX_DOCUMENTS)
{
--LOOLWSD::NumDocBrokers;
Log::error("Maximum number of open documents reached.");
throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_LIMIT_REACHED);
}
#endif
// Set one we just created.
Log::debug("New DocumentBroker for docKey [" + docKey + "].");
docBroker = std::make_shared<DocumentBroker>(uriPublic, docKey, LOOLWSD::ChildRoot, child);
@ -609,6 +618,9 @@ private:
// Remove.
std::unique_lock<std::mutex> lock(docBrokersMutex);
docBrokers.erase(docKey);
#if MAX_DOCUMENTS > 0
--LOOLWSD::NumDocBrokers;
#endif
}
throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_INTERNAL_ERROR);
@ -723,6 +735,9 @@ private:
std::unique_lock<std::mutex> docBrokersLock(docBrokersMutex);
Log::debug("Removing DocumentBroker for docKey [" + docKey + "].");
docBrokers.erase(docKey);
#if MAX_DOCUMENTS > 0
--LOOLWSD::NumDocBrokers;
#endif
Log::info("Removing complete doc [" + docKey + "] from Admin.");
Admin::instance().rmDoc(docKey);
}
@ -810,7 +825,20 @@ public:
request, response))
return;
#if MAX_CONNECTIONS > 0
if (++LOOLWSD::NumConnections > MAX_CONNECTIONS)
{
--LOOLWSD::NumConnections;
Log::error("Maximum number of connections reached.");
throw WebSocketErrorMessageException(SERVICE_UNAVALABLE_LIMIT_REACHED);
}
#endif
handleClientRequest(request,response);
#if MAX_CONNECTIONS > 0
--LOOLWSD::NumConnections;
#endif
}
static void handleClientRequest(HTTPServerRequest& request, HTTPServerResponse& response)
@ -1197,6 +1225,8 @@ bool LOOLWSD::SSLEnabled =
static std::string UnitTestLibrary;
unsigned int LOOLWSD::NumPreSpawnedChildren = 0;
std::atomic<unsigned> LOOLWSD::NumDocBrokers;
std::atomic<unsigned> LOOLWSD::NumConnections;
class AppConfigMap : public Poco::Util::MapConfiguration
{
@ -1293,6 +1323,17 @@ void LOOLWSD::initialize(Application& self)
setenv("MAX_CONCURRENCY", std::to_string(maxConcurrency).c_str(), 1);
}
// In Trial Versions we might want to set some limits.
LOOLWSD::NumDocBrokers = 0;
LOOLWSD::NumConnections = 0;
Log::info() << "Open Documents Limit: " << (MAX_DOCUMENTS > 0 ?
std::to_string(MAX_DOCUMENTS) :
std::string("unlimited")) << Log::end;
Log::info() << "Client Connections Limit: " << (MAX_CONNECTIONS > 0 ?
std::to_string(MAX_CONNECTIONS) :
std::string("unlimited")) << Log::end;
StorageBase::initialize();
ServerApplication::initialize(self);

View File

@ -44,6 +44,8 @@ public:
static std::string FileServerRoot;
static std::string LOKitVersion;
static bool SSLEnabled;
static std::atomic<unsigned> NumDocBrokers;
static std::atomic<unsigned> NumConnections;
static
std::string GenSessionId()

View File

@ -13,6 +13,7 @@
#define INCLUDED_USERMESSAGES_HPP
constexpr auto SERVICE_UNAVALABLE_INTERNAL_ERROR = "Service is unavailable. Please try again later and report to your administrator if the issue persists.";
constexpr auto SERVICE_UNAVALABLE_LIMIT_REACHED = "This server has reached the number of connections or documents it supports at a given time.";
#endif

View File

@ -80,6 +80,14 @@ AC_ARG_ENABLE([ssl],
AS_HELP_STRING([--disable-ssl],
[Compile without SSL support]))
AC_ARG_WITH([max-documents],
AS_HELP_STRING([--max-documents],
[Compile with a hard-coded limit on the number of documents]))
AC_ARG_WITH([max-connections],
AS_HELP_STRING([--max-connections],
[Compile with a hard-coded limit on the total number of client connections]))
# Handle options
AS_IF([test "$enable_debug" = yes -a -n "$with_poco_libs"],
[POCO_DEBUG_SUFFIX=d],
@ -96,6 +104,18 @@ else
fi
AC_SUBST(ENABLE_DEBUG)
MAX_DOCUMENTS=0
AS_IF([test -n "$with_max_documents"],
[MAX_DOCUMENTS="$with_max_documents"])
AC_DEFINE_UNQUOTED([MAX_DOCUMENTS],[$MAX_DOCUMENTS],[Limit the maximum number of open documents])
AC_SUBST(MAX_DOCUMENTS)
MAX_CONNECTIONS=0
AS_IF([test -n "$with_max_connections"],
[MAX_CONNECTIONS="$with_max_connections"])
AC_DEFINE_UNQUOTED([MAX_CONNECTIONS],[$MAX_CONNECTIONS],[Limit the maximum number of open documents])
AC_SUBST(MAX_CONNECTIONS)
# Test for build environment
CXXFLAGS="$CXXFLAGS -std=c++11"