1
0
Fork 0

Bug fix/cleanup commtasks (#8893)

This commit is contained in:
Jan 2019-05-08 16:33:19 +02:00 committed by GitHub
parent 014490e459
commit 30e9fbafe0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 171 additions and 72 deletions

View File

@ -25,6 +25,7 @@
#include "GeneralCommTask.h" #include "GeneralCommTask.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/compile-time-strlen.h" #include "Basics/compile-time-strlen.h"
#include "Basics/HybridLogicalClock.h" #include "Basics/HybridLogicalClock.h"
#include "Basics/Locking.h" #include "Basics/Locking.h"
@ -72,11 +73,13 @@ inline bool startsWith(std::string const& path, char const* other) {
// --SECTION-- constructors and destructors // --SECTION-- constructors and destructors
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
GeneralCommTask::GeneralCommTask(GeneralServer& server, GeneralServer::IoContext& context, GeneralCommTask::GeneralCommTask(GeneralServer& server,
std::unique_ptr<Socket> socket, ConnectionInfo&& info, GeneralServer::IoContext& context,
char const* name,
std::unique_ptr<Socket> socket,
ConnectionInfo&& info,
double keepAliveTimeout, bool skipSocketInit) double keepAliveTimeout, bool skipSocketInit)
: IoTask(server, context, "GeneralCommTask"), : SocketTask(server, context, name, std::move(socket), std::move(info),
SocketTask(server, context, std::move(socket), std::move(info),
keepAliveTimeout, skipSocketInit), keepAliveTimeout, skipSocketInit),
_auth(AuthenticationFeature::instance()), _auth(AuthenticationFeature::instance()),
_authToken("", false, 0.) { _authToken("", false, 0.) {
@ -446,6 +449,9 @@ void GeneralCommTask::addErrorResponse(rest::ResponseCode code, rest::ContentTyp
bool GeneralCommTask::handleRequestSync(std::shared_ptr<RestHandler> handler) { bool GeneralCommTask::handleRequestSync(std::shared_ptr<RestHandler> handler) {
auto const lane = handler->getRequestLane(); auto const lane = handler->getRequestLane();
auto self = shared_from_this(); auto self = shared_from_this();
if (application_features::ApplicationServer::isStopping()) {
return false;
}
bool ok = SchedulerFeature::SCHEDULER->queue(lane, [self, this, handler]() { bool ok = SchedulerFeature::SCHEDULER->queue(lane, [self, this, handler]() {
handleRequestDirectly(basics::ConditionalLocking::DoLock, std::move(handler)); handleRequestDirectly(basics::ConditionalLocking::DoLock, std::move(handler));
@ -466,11 +472,14 @@ void GeneralCommTask::handleRequestDirectly(bool doLock, std::shared_ptr<RestHan
TRI_ASSERT(doLock || _peer->runningInThisThread()); TRI_ASSERT(doLock || _peer->runningInThisThread());
auto self = shared_from_this(); auto self = shared_from_this();
handler->runHandler([self, this](rest::RestHandler* handler) { if (application_features::ApplicationServer::isStopping()) {
return;
}
handler->runHandler([self = std::move(self), this](rest::RestHandler* handler) {
RequestStatistics* stat = handler->stealStatistics(); RequestStatistics* stat = handler->stealStatistics();
auto h = handler->shared_from_this(); auto h = handler->shared_from_this();
// Pass the response the io context // Pass the response the io context
_peer->post([self, this, stat, h]() { addResponse(*(h->response()), stat); }); _peer->post([self, this, stat, h = std::move(h)]() { addResponse(*(h->response()), stat); });
}); });
} }
@ -478,20 +487,23 @@ void GeneralCommTask::handleRequestDirectly(bool doLock, std::shared_ptr<RestHan
bool GeneralCommTask::handleRequestAsync(std::shared_ptr<RestHandler> handler, bool GeneralCommTask::handleRequestAsync(std::shared_ptr<RestHandler> handler,
uint64_t* jobId) { uint64_t* jobId) {
auto self = shared_from_this(); auto self = shared_from_this();
if (application_features::ApplicationServer::isStopping()) {
return false;
}
if (jobId != nullptr) { if (jobId != nullptr) {
GeneralServerFeature::JOB_MANAGER->initAsyncJob(handler); GeneralServerFeature::JOB_MANAGER->initAsyncJob(handler);
*jobId = handler->handlerId(); *jobId = handler->handlerId();
// callback will persist the response with the AsyncJobManager // callback will persist the response with the AsyncJobManager
return SchedulerFeature::SCHEDULER->queue(handler->getRequestLane(), [self, handler] { return SchedulerFeature::SCHEDULER->queue(handler->getRequestLane(), [self = std::move(self), handler] {
handler->runHandler([](RestHandler* h) { handler->runHandler([](RestHandler* h) {
GeneralServerFeature::JOB_MANAGER->finishAsyncJob(h); GeneralServerFeature::JOB_MANAGER->finishAsyncJob(h);
}); });
}); });
} else { } else {
// here the response will just be ignored // here the response will just be ignored
return SchedulerFeature::SCHEDULER->queue(handler->getRequestLane(), [self, handler] { return SchedulerFeature::SCHEDULER->queue(handler->getRequestLane(), [self = std::move(self), handler] {
handler->runHandler([](RestHandler*) {}); handler->runHandler([](RestHandler*) {});
}); });
} }

View File

@ -86,9 +86,13 @@ class GeneralCommTask : public SocketTask {
GeneralCommTask const& operator=(GeneralCommTask const&) = delete; GeneralCommTask const& operator=(GeneralCommTask const&) = delete;
public: public:
GeneralCommTask(GeneralServer& server, GeneralServer::IoContext&, GeneralCommTask(GeneralServer& server,
std::unique_ptr<Socket>, ConnectionInfo&&, GeneralServer::IoContext&,
double keepAliveTimeout, bool skipSocketInit = false); char const* name,
std::unique_ptr<Socket>,
ConnectionInfo&&,
double keepAliveTimeout,
bool skipSocketInit = false);
~GeneralCommTask(); ~GeneralCommTask();

View File

@ -29,9 +29,6 @@
#include "GeneralServer/GeneralServer.h" #include "GeneralServer/GeneralServer.h"
#include "GeneralServer/GeneralServerFeature.h" #include "GeneralServer/GeneralServerFeature.h"
#include "GeneralServer/HttpCommTask.h" #include "GeneralServer/HttpCommTask.h"
#include "Rest/HttpRequest.h"
#include "Scheduler/Scheduler.h"
#include "Scheduler/SchedulerFeature.h"
using namespace arangodb; using namespace arangodb;
using namespace arangodb::rest; using namespace arangodb::rest;
@ -42,8 +39,7 @@ using namespace arangodb::rest;
GeneralListenTask::GeneralListenTask(GeneralServer& server, GeneralServer::IoContext& context, GeneralListenTask::GeneralListenTask(GeneralServer& server, GeneralServer::IoContext& context,
Endpoint* endpoint, ProtocolType connectionType) Endpoint* endpoint, ProtocolType connectionType)
: IoTask(server, context, "GeneralListenTask"), : ListenTask(server, context, "GeneralListenTask", endpoint),
ListenTask(server, context, endpoint),
_connectionType(connectionType) { _connectionType(connectionType) {
_keepAliveTimeout = GeneralServerFeature::keepAliveTimeout(); _keepAliveTimeout = GeneralServerFeature::keepAliveTimeout();
@ -54,8 +50,13 @@ void GeneralListenTask::handleConnected(std::unique_ptr<Socket> socket,
ConnectionInfo&& info) { ConnectionInfo&& info) {
auto commTask = std::make_shared<HttpCommTask>(_server, _context, std::move(socket), auto commTask = std::make_shared<HttpCommTask>(_server, _context, std::move(socket),
std::move(info), _keepAliveTimeout); std::move(info), _keepAliveTimeout);
bool res = commTask->start();
LOG_TOPIC_IF("54790", DEBUG, Logger::COMMUNICATION, res) << "Started comm task"; _server.registerTask(commTask);
LOG_TOPIC_IF("56754", DEBUG, Logger::COMMUNICATION, !res)
<< "Failed to start comm task"; if (commTask->start()) {
LOG_TOPIC("54790", DEBUG, Logger::COMMUNICATION) << "Started comm task";
} else {
LOG_TOPIC("56754", DEBUG, Logger::COMMUNICATION) << "Failed to start comm task";
_server.unregisterTask(commTask->id());
}
} }

View File

@ -24,14 +24,21 @@
#include "GeneralServer.h" #include "GeneralServer.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/MutexLocker.h"
#include "Basics/exitcodes.h" #include "Basics/exitcodes.h"
#include "Endpoint/Endpoint.h"
#include "Endpoint/EndpointList.h" #include "Endpoint/EndpointList.h"
#include "GeneralServer/GeneralDefinitions.h" #include "GeneralServer/GeneralDefinitions.h"
#include "GeneralServer/GeneralListenTask.h" #include "GeneralServer/GeneralListenTask.h"
#include "GeneralServer/SocketTask.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Scheduler/Scheduler.h" #include "Scheduler/Scheduler.h"
#include "Scheduler/SchedulerFeature.h" #include "Scheduler/SchedulerFeature.h"
#include <chrono>
#include <thread>
using namespace arangodb; using namespace arangodb;
using namespace arangodb::basics; using namespace arangodb::basics;
using namespace arangodb::rest; using namespace arangodb::rest;
@ -42,6 +49,22 @@ using namespace arangodb::rest;
GeneralServer::GeneralServer(uint64_t numIoThreads) GeneralServer::GeneralServer(uint64_t numIoThreads)
: _numIoThreads(numIoThreads), _contexts(numIoThreads) {} : _numIoThreads(numIoThreads), _contexts(numIoThreads) {}
GeneralServer::~GeneralServer() {}
void GeneralServer::registerTask(std::shared_ptr<rest::SocketTask> const& task) {
if (application_features::ApplicationServer::isStopping()) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_SHUTTING_DOWN);
}
MUTEX_LOCKER(locker, _tasksLock);
_commTasks.emplace(task->id(), task);
}
void GeneralServer::unregisterTask(uint64_t id) {
MUTEX_LOCKER(locker, _tasksLock);
_commTasks.erase(id);
}
void GeneralServer::setEndpointList(EndpointList const* list) { void GeneralServer::setEndpointList(EndpointList const* list) {
_endpointList = list; _endpointList = list;
} }
@ -71,9 +94,36 @@ void GeneralServer::startListening() {
} }
void GeneralServer::stopListening() { void GeneralServer::stopListening() {
for (auto& task : _listenTasks) {
task->stop();
}
// close connections of all socket tasks so the tasks will
// eventually shut themselves down
MUTEX_LOCKER(lock, _tasksLock);
for (auto& task : _commTasks) {
task.second->closeStream();
}
}
void GeneralServer::stopWorking() {
for (auto& context : _contexts) { for (auto& context : _contexts) {
context.stop(); context.stop();
} }
_listenTasks.clear();
while (true) {
{
MUTEX_LOCKER(lock, _tasksLock);
if (_commTasks.empty()) {
break;
}
}
LOG_TOPIC("f1549", DEBUG, Logger::FIXME) << "waiting for " << _commTasks.size() << " comm tasks to shut down";
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -90,11 +140,9 @@ bool GeneralServer::openEndpoint(IoContext& ioContext, Endpoint* endpoint) {
} }
auto task = std::make_shared<GeneralListenTask>(*this, ioContext, endpoint, protocolType); auto task = std::make_shared<GeneralListenTask>(*this, ioContext, endpoint, protocolType);
if (!task->start()) { _listenTasks.emplace_back(task);
return false;
}
return true; return task->start();
} }
GeneralServer::IoThread::IoThread(IoContext& iocontext) GeneralServer::IoThread::IoThread(IoContext& iocontext)
@ -117,7 +165,9 @@ GeneralServer::IoContext::IoContext()
GeneralServer::IoContext::~IoContext() { stop(); } GeneralServer::IoContext::~IoContext() { stop(); }
void GeneralServer::IoContext::stop() { _asioIoContext.stop(); } void GeneralServer::IoContext::stop() {
_asioIoContext.stop();
}
GeneralServer::IoContext& GeneralServer::selectIoContext() { GeneralServer::IoContext& GeneralServer::selectIoContext() {
uint64_t low = _contexts[0]._clients.load(); uint64_t low = _contexts[0]._clients.load();

View File

@ -27,14 +27,17 @@
#define ARANGOD_HTTP_SERVER_HTTP_SERVER_H 1 #define ARANGOD_HTTP_SERVER_HTTP_SERVER_H 1
#include "Basics/Common.h" #include "Basics/Common.h"
#include "Basics/Mutex.h"
#include "Basics/Thread.h" #include "Basics/Thread.h"
#include "Basics/asio_ns.h" #include "Basics/asio_ns.h"
#include "Endpoint/Endpoint.h"
namespace arangodb { namespace arangodb {
class Endpoint;
class EndpointList; class EndpointList;
namespace rest { namespace rest {
class GeneralListenTask;
class SocketTask;
class GeneralServer { class GeneralServer {
GeneralServer(GeneralServer const&) = delete; GeneralServer(GeneralServer const&) = delete;
@ -42,11 +45,15 @@ class GeneralServer {
public: public:
explicit GeneralServer(uint64_t numIoThreads); explicit GeneralServer(uint64_t numIoThreads);
~GeneralServer();
public: public:
void registerTask(std::shared_ptr<rest::SocketTask> const&);
void unregisterTask(uint64_t id);
void setEndpointList(EndpointList const* list); void setEndpointList(EndpointList const* list);
void startListening(); void startListening();
void stopListening(); void stopListening();
void stopWorking();
class IoContext; class IoContext;
@ -137,9 +144,13 @@ class GeneralServer {
friend class IoThread; friend class IoThread;
friend class IoContext; friend class IoContext;
uint64_t _numIoThreads; uint64_t const _numIoThreads;
std::vector<IoContext> _contexts; std::vector<IoContext> _contexts;
EndpointList const* _endpointList = nullptr; EndpointList const* _endpointList = nullptr;
Mutex _tasksLock;
std::vector<std::shared_ptr<rest::GeneralListenTask>> _listenTasks;
std::unordered_map<uint64_t, std::shared_ptr<rest::SocketTask>> _commTasks;
}; };
} // namespace rest } // namespace rest
} // namespace arangodb } // namespace arangodb

View File

@ -239,15 +239,24 @@ void GeneralServerFeature::start() {
} }
} }
void GeneralServerFeature::stop() { void GeneralServerFeature::beginShutdown() {
for (auto& server : _servers) { for (auto& server : _servers) {
server->stopListening(); server->stopListening();
} }
}
void GeneralServerFeature::stop() {
for (auto& server : _servers) {
server->stopWorking();
}
_jobManager->deleteJobs(); _jobManager->deleteJobs();
} }
void GeneralServerFeature::unprepare() { void GeneralServerFeature::unprepare() {
for (auto& server : _servers) {
server->stopWorking();
}
_servers.clear(); _servers.clear();
_jobManager.reset(); _jobManager.reset();

View File

@ -93,6 +93,7 @@ class GeneralServerFeature final : public application_features::ApplicationFeatu
void validateOptions(std::shared_ptr<options::ProgramOptions>) override final; void validateOptions(std::shared_ptr<options::ProgramOptions>) override final;
void prepare() override final; void prepare() override final;
void start() override final; void start() override final;
void beginShutdown() override final;
void stop() override final; void stop() override final;
void unprepare() override final; void unprepare() override final;

View File

@ -34,6 +34,7 @@
#include "GeneralServer/VstCommTask.h" #include "GeneralServer/VstCommTask.h"
#include "Meta/conversion.h" #include "Meta/conversion.h"
#include "Rest/HttpRequest.h" #include "Rest/HttpRequest.h"
#include "Rest/HttpResponse.h"
#include "Statistics/ConnectionStatistics.h" #include "Statistics/ConnectionStatistics.h"
#include "Utils/Events.h" #include "Utils/Events.h"
@ -49,8 +50,7 @@ size_t const HttpCommTask::RunCompactEvery = 500;
HttpCommTask::HttpCommTask(GeneralServer& server, GeneralServer::IoContext& context, HttpCommTask::HttpCommTask(GeneralServer& server, GeneralServer::IoContext& context,
std::unique_ptr<Socket> socket, std::unique_ptr<Socket> socket,
ConnectionInfo&& info, double timeout) ConnectionInfo&& info, double timeout)
: IoTask(server, context, "HttpCommTask"), : GeneralCommTask(server, context, "HttpCommTask", std::move(socket), std::move(info), timeout),
GeneralCommTask(server, context, std::move(socket), std::move(info), timeout),
_readPosition(0), _readPosition(0),
_startPosition(0), _startPosition(0),
_bodyPosition(0), _bodyPosition(0),
@ -69,6 +69,8 @@ HttpCommTask::HttpCommTask(GeneralServer& server, GeneralServer::IoContext& cont
ConnectionStatistics::SET_HTTP(_connectionStatistics); ConnectionStatistics::SET_HTTP(_connectionStatistics);
} }
HttpCommTask::~HttpCommTask() {}
// whether or not this task can mix sync and async I/O // whether or not this task can mix sync and async I/O
bool HttpCommTask::canUseMixedIO() const { bool HttpCommTask::canUseMixedIO() const {
// in case SSL is used, we cannot use a combination of sync and async I/O // in case SSL is used, we cannot use a combination of sync and async I/O
@ -293,11 +295,16 @@ bool HttpCommTask::processRead(double startTime) {
"task is already abandoned"); "task is already abandoned");
} }
_server.unregisterTask(this->id());
std::shared_ptr<GeneralCommTask> commTask = std::shared_ptr<GeneralCommTask> commTask =
std::make_shared<VstCommTask>(_server, _context, std::move(_peer), std::make_shared<VstCommTask>(_server, _context, std::move(_peer),
std::move(_connectionInfo), std::move(_connectionInfo),
GeneralServerFeature::keepAliveTimeout(), protocolVersion, GeneralServerFeature::keepAliveTimeout(), protocolVersion,
/*skipSocketInit*/ true); /*skipSocketInit*/ true);
_server.registerTask(commTask);
commTask->addToReadBuffer(_readBuffer.c_str() + 11, _readBuffer.length() - 11); commTask->addToReadBuffer(_readBuffer.c_str() + 11, _readBuffer.length() - 11);
commTask->processAll(); commTask->processAll();
commTask->start(); commTask->start();

View File

@ -3,7 +3,6 @@
#include "Basics/Common.h" #include "Basics/Common.h"
#include "GeneralServer/GeneralCommTask.h" #include "GeneralServer/GeneralCommTask.h"
#include "Rest/HttpResponse.h"
namespace arangodb { namespace arangodb {
class HttpRequest; class HttpRequest;
@ -20,6 +19,8 @@ class HttpCommTask final : public GeneralCommTask {
HttpCommTask(GeneralServer& server, GeneralServer::IoContext& context, HttpCommTask(GeneralServer& server, GeneralServer::IoContext& context,
std::unique_ptr<Socket> socket, ConnectionInfo&&, double timeout); std::unique_ptr<Socket> socket, ConnectionInfo&&, double timeout);
~HttpCommTask();
arangodb::Endpoint::TransportType transportType() override { arangodb::Endpoint::TransportType transportType() override {
return arangodb::Endpoint::TransportType::HTTP; return arangodb::Endpoint::TransportType::HTTP;
} }

View File

@ -24,15 +24,13 @@
#include "IoTask.h" #include "IoTask.h"
#include <velocypack/Builder.h>
#include <velocypack/velocypack-aliases.h>
using namespace arangodb::rest; using namespace arangodb::rest;
namespace { namespace {
std::atomic_uint_fast64_t NEXT_IO_TASK_ID(static_cast<uint64_t>(TRI_microtime() * 100000.0)); std::atomic_uint_fast64_t NEXT_IO_TASK_ID(static_cast<uint64_t>(TRI_microtime() * 100000.0));
} }
IoTask::IoTask(GeneralServer& server, GeneralServer::IoContext& context, IoTask::IoTask(GeneralServer& server,
std::string const& name) GeneralServer::IoContext& context,
: _context(context), _server(server), _taskId(NEXT_IO_TASK_ID++), _name(name) {} char const* name)
: _context(context), _server(server), _taskId(++NEXT_IO_TASK_ID), _name(name) {}

View File

@ -29,10 +29,6 @@
#include "GeneralServer/GeneralServer.h" #include "GeneralServer/GeneralServer.h"
namespace arangodb { namespace arangodb {
namespace velocypack {
class Builder;
}
namespace rest { namespace rest {
class IoTask : public std::enable_shared_from_this<IoTask> { class IoTask : public std::enable_shared_from_this<IoTask> {
@ -40,11 +36,18 @@ class IoTask : public std::enable_shared_from_this<IoTask> {
IoTask& operator=(IoTask const&) = delete; IoTask& operator=(IoTask const&) = delete;
public: public:
IoTask(GeneralServer& server, GeneralServer::IoContext&, std::string const& name); IoTask(GeneralServer& server,
GeneralServer::IoContext&,
char const* name);
virtual ~IoTask() = default; virtual ~IoTask() = default;
public: public:
std::string const& name() const { return _name; } // doesn't seem to be called right now, but can be used for debugging
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
char const* name() const { return _name; }
#endif
uint64_t id() const { return _taskId; }
protected: protected:
GeneralServer::IoContext& _context; GeneralServer::IoContext& _context;
@ -52,7 +55,7 @@ class IoTask : public std::enable_shared_from_this<IoTask> {
uint64_t const _taskId; uint64_t const _taskId;
private: private:
std::string const _name; char const* _name;
}; };
} // namespace rest } // namespace rest
} // namespace arangodb } // namespace arangodb

View File

@ -36,9 +36,11 @@ using namespace arangodb::rest;
// --SECTION-- constructors and destructors // --SECTION-- constructors and destructors
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
ListenTask::ListenTask(GeneralServer& server, GeneralServer::IoContext& context, ListenTask::ListenTask(GeneralServer& server,
GeneralServer::IoContext& context,
char const* name,
Endpoint* endpoint) Endpoint* endpoint)
: IoTask(server, context, "ListenTask"), : IoTask(server, context, name),
_endpoint(endpoint), _endpoint(endpoint),
_bound(false), _bound(false),
_acceptor(Acceptor::factory(server, context, endpoint)) {} _acceptor(Acceptor::factory(server, context, endpoint)) {}
@ -54,11 +56,6 @@ bool ListenTask::start() {
try { try {
_acceptor->open(); _acceptor->open();
} catch (asio_ns::system_error const& err) {
LOG_TOPIC("c476e", WARN, arangodb::Logger::COMMUNICATION)
<< "failed to open endpoint '" << _endpoint->specification()
<< "' with error: " << err.what();
return false;
} catch (std::exception const& err) { } catch (std::exception const& err) {
LOG_TOPIC("7c359", WARN, arangodb::Logger::COMMUNICATION) LOG_TOPIC("7c359", WARN, arangodb::Logger::COMMUNICATION)
<< "failed to open endpoint '" << _endpoint->specification() << "failed to open endpoint '" << _endpoint->specification()
@ -79,26 +76,26 @@ void ListenTask::accept() {
if (ec) { if (ec) {
if (ec == asio_ns::error::operation_aborted) { if (ec == asio_ns::error::operation_aborted) {
LOG_TOPIC("74339", WARN, arangodb::Logger::FIXME) << "accept failed: " << ec.message(); // this "error" is accpepted, so it doesn't justify a warning
LOG_TOPIC("74339", DEBUG, arangodb::Logger::FIXME) << "accept failed: " << ec.message();
return; return;
} }
++_acceptFailures; ++_acceptFailures;
if (_acceptFailures < MAX_ACCEPT_ERRORS) { if (_acceptFailures <= MAX_ACCEPT_ERRORS) {
LOG_TOPIC("644df", WARN, arangodb::Logger::FIXME) << "accept failed: " << ec.message(); LOG_TOPIC("644df", WARN, arangodb::Logger::FIXME) << "accept failed: " << ec.message();
} else if (_acceptFailures == MAX_ACCEPT_ERRORS) { if (_acceptFailures == MAX_ACCEPT_ERRORS) {
LOG_TOPIC("302eb", WARN, arangodb::Logger::FIXME) << "accept failed: " << ec.message();
LOG_TOPIC("40ca3", WARN, arangodb::Logger::FIXME) LOG_TOPIC("40ca3", WARN, arangodb::Logger::FIXME)
<< "too many accept failures, stopping to report"; << "too many accept failures, stopping to report";
} }
} }
}
ConnectionInfo info;
std::unique_ptr<Socket> peer = _acceptor->movePeer(); std::unique_ptr<Socket> peer = _acceptor->movePeer();
// set the endpoint // set the endpoint
ConnectionInfo info;
info.endpoint = _endpoint->specification(); info.endpoint = _endpoint->specification();
info.endpointType = _endpoint->domainType(); info.endpointType = _endpoint->domainType();
info.encryptionType = _endpoint->encryption(); info.encryptionType = _endpoint->encryption();
@ -122,5 +119,4 @@ void ListenTask::stop() {
_bound = false; _bound = false;
_acceptor->close(); _acceptor->close();
_acceptor.reset();
} }

View File

@ -37,12 +37,15 @@
namespace arangodb { namespace arangodb {
class ListenTask : virtual public rest::IoTask { class ListenTask : public rest::IoTask {
public: public:
static size_t const MAX_ACCEPT_ERRORS = 128; static size_t const MAX_ACCEPT_ERRORS = 128;
public: public:
ListenTask(rest::GeneralServer& server, rest::GeneralServer::IoContext&, Endpoint*); ListenTask(rest::GeneralServer& server,
rest::GeneralServer::IoContext&,
char const* name,
Endpoint*);
~ListenTask(); ~ListenTask();
public: public:
@ -58,7 +61,6 @@ class ListenTask : virtual public rest::IoTask {
void accept(); void accept();
Endpoint* _endpoint; Endpoint* _endpoint;
size_t _acceptFailures = 0; size_t _acceptFailures = 0;
bool _bound; bool _bound;
std::unique_ptr<Acceptor> _acceptor; std::unique_ptr<Acceptor> _acceptor;

View File

@ -43,11 +43,14 @@ using namespace arangodb::rest;
// --SECTION-- constructors and destructors // --SECTION-- constructors and destructors
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
SocketTask::SocketTask(GeneralServer& server, GeneralServer::IoContext& context, SocketTask::SocketTask(GeneralServer& server,
GeneralServer::IoContext& context,
char const* name,
std::unique_ptr<arangodb::Socket> socket, std::unique_ptr<arangodb::Socket> socket,
arangodb::ConnectionInfo&& connectionInfo, arangodb::ConnectionInfo&& connectionInfo,
double keepAliveTimeout, bool skipInit = false) double keepAliveTimeout,
: IoTask(server, context, "SocketTask"), bool skipInit = false)
: IoTask(server, context, name),
_peer(std::move(socket)), _peer(std::move(socket)),
_connectionInfo(std::move(connectionInfo)), _connectionInfo(std::move(connectionInfo)),
_connectionStatistics(nullptr), _connectionStatistics(nullptr),
@ -191,7 +194,6 @@ void SocketTask::closeStream() {
// strand::dispatch may execute this immediately if this // strand::dispatch may execute this immediately if this
// is called on a thread inside the same strand // is called on a thread inside the same strand
auto self = shared_from_this(); auto self = shared_from_this();
_peer->post([self, this] { closeStreamNoLock(); }); _peer->post([self, this] { closeStreamNoLock(); });
} }
@ -214,6 +216,8 @@ void SocketTask::closeStreamNoLock() {
_closeRequested.store(false, std::memory_order_release); _closeRequested.store(false, std::memory_order_release);
_keepAliveTimer->cancel(); _keepAliveTimer->cancel();
_keepAliveTimerActive.store(false, std::memory_order_relaxed); _keepAliveTimerActive.store(false, std::memory_order_relaxed);
_server.unregisterTask(this->id());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -42,8 +42,9 @@ namespace arangodb {
class ConnectionStatistics; class ConnectionStatistics;
namespace rest { namespace rest {
class SocketTask : virtual public IoTask { class SocketTask : public IoTask {
friend class HttpCommTask; friend class HttpCommTask;
friend class GeneralServer;
explicit SocketTask(SocketTask const&) = delete; explicit SocketTask(SocketTask const&) = delete;
SocketTask& operator=(SocketTask const&) = delete; SocketTask& operator=(SocketTask const&) = delete;
@ -53,6 +54,7 @@ class SocketTask : virtual public IoTask {
public: public:
SocketTask(GeneralServer& server, GeneralServer::IoContext& context, SocketTask(GeneralServer& server, GeneralServer::IoContext& context,
char const* name,
std::unique_ptr<Socket>, ConnectionInfo&&, double keepAliveTimeout, std::unique_ptr<Socket>, ConnectionInfo&&, double keepAliveTimeout,
bool skipInit); bool skipInit);

View File

@ -82,8 +82,7 @@ inline void validateMessage(char const* vpStart, char const* vpEnd) {
VstCommTask::VstCommTask(GeneralServer& server, GeneralServer::IoContext& context, VstCommTask::VstCommTask(GeneralServer& server, GeneralServer::IoContext& context,
std::unique_ptr<Socket> socket, ConnectionInfo&& info, std::unique_ptr<Socket> socket, ConnectionInfo&& info,
double timeout, ProtocolVersion protocolVersion, bool skipInit) double timeout, ProtocolVersion protocolVersion, bool skipInit)
: IoTask(server, context, "VstCommTask"), : GeneralCommTask(server, context, "VstCommTask", std::move(socket), std::move(info), timeout, skipInit),
GeneralCommTask(server, context, std::move(socket), std::move(info), timeout, skipInit),
_authorized(!_auth->isActive()), _authorized(!_auth->isActive()),
_authMethod(rest::AuthenticationMethod::NONE), _authMethod(rest::AuthenticationMethod::NONE),
_protocolVersion(protocolVersion) { _protocolVersion(protocolVersion) {

View File

@ -23,12 +23,11 @@
#include "LocalTaskQueue.h" #include "LocalTaskQueue.h"
#include "ApplicationFeatures/ApplicationServer.h"
#include "Basics/ConditionLocker.h" #include "Basics/ConditionLocker.h"
#include "Basics/Exceptions.h" #include "Basics/Exceptions.h"
#include "Basics/MutexLocker.h" #include "Basics/MutexLocker.h"
#include "Logger/Logger.h" #include "Logger/Logger.h"
#include "Scheduler/Scheduler.h"
#include "Scheduler/SchedulerFeature.h"
using namespace arangodb::basics; using namespace arangodb::basics;