1
0
Fork 0

added work monitor call

This commit is contained in:
Frank Celler 2016-01-13 17:40:24 +01:00
parent 46c46e9eaf
commit 89ca0ffae1
24 changed files with 338 additions and 308 deletions

View File

@ -193,6 +193,7 @@ add_executable(
RestHandler/RestUploadHandler.cpp
RestHandler/RestVersionHandler.cpp
RestHandler/RestVocbaseBaseHandler.cpp
RestHandler/WorkMonitorHandler.cpp
RestServer/ArangoServer.cpp
RestServer/ConsoleThread.cpp
RestServer/VocbaseContext.cpp

View File

@ -966,7 +966,6 @@ bool HttpCommTask::setup(Scheduler* scheduler, EventLoop loop) {
_scheduler = scheduler;
_loop = loop;
_server->registerChunkedTask(this);
setupDone();
return true;
@ -1030,7 +1029,6 @@ void HttpCommTask::signalTask(TaskData* data) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -1100,5 +1098,3 @@ void HttpCommTask::handleTimeout() {
_clientClosed = true;
_server->handleCommunicationClosed(this);
}

View File

@ -108,7 +108,6 @@ void HttpHandler::addResponse(HttpHandler*) {
// nothing by default
}
//////////////////////////////////////////////////////////////////////////////
/// @brief returns the id of the underlying task
//////////////////////////////////////////////////////////////////////////////
@ -163,7 +162,7 @@ HttpHandler::status_t HttpHandler::executeFull() {
finalizeExecute();
if (_response == nullptr) {
if (status._status != HANDLER_ASYNC && _response == nullptr) {
Exception err(TRI_ERROR_INTERNAL, "no response received from handler",
__FILE__, __LINE__);
@ -183,7 +182,7 @@ HttpHandler::status_t HttpHandler::executeFull() {
LOG_ERROR("caught exception");
}
if (_response == nullptr) {
if (status._status != HANDLER_ASYNC && _response == nullptr) {
_response = new HttpResponse(HttpResponse::SERVER_ERROR,
HttpRequest::MinCompatibility);
}

View File

@ -74,7 +74,7 @@ class HttpHandler : public RequestStatisticsAgent, public arangodb::WorkItem {
/// @brief status of execution
//////////////////////////////////////////////////////////////////////////////
enum status_e { HANDLER_DONE, HANDLER_FAILED };
enum status_e { HANDLER_DONE, HANDLER_FAILED, HANDLER_ASYNC };
//////////////////////////////////////////////////////////////////////////////
/// @brief result of execution

View File

@ -42,38 +42,15 @@ using namespace arangodb;
using namespace triagens::basics;
using namespace triagens::rest;
////////////////////////////////////////////////////////////////////////////////
/// @brief map of ChunkedTask
////////////////////////////////////////////////////////////////////////////////
static std::unordered_map<uint64_t, HttpCommTask*> HttpCommTaskMap;
////////////////////////////////////////////////////////////////////////////////
/// @brief lock for the above map
////////////////////////////////////////////////////////////////////////////////
static Mutex HttpCommTaskMapLock;
////////////////////////////////////////////////////////////////////////////////
/// @brief destroys an endpoint server
////////////////////////////////////////////////////////////////////////////////
int HttpServer::sendChunk(uint64_t taskId, std::string const& data) {
MUTEX_LOCKER(HttpCommTaskMapLock);
auto&& it = HttpCommTaskMap.find(taskId);
if (it == HttpCommTaskMap.end()) {
return TRI_ERROR_TASK_NOT_FOUND;
}
std::unique_ptr<TaskData> taskData(new TaskData());
taskData->_taskId = taskId;
taskData->_loop = it->second->eventLoop();
taskData->_loop = Scheduler::SCHEDULER->lookupLoopById(taskId);
taskData->_type = TaskData::TASK_DATA_CHUNK;
taskData->_data = data;
@ -82,7 +59,6 @@ int HttpServer::sendChunk(uint64_t taskId, std::string const& data) {
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new general server with dispatcher and job manager
////////////////////////////////////////////////////////////////////////////////
@ -103,15 +79,7 @@ HttpServer::HttpServer(Scheduler* scheduler, Dispatcher* dispatcher,
/// @brief destructs a general server
////////////////////////////////////////////////////////////////////////////////
HttpServer::~HttpServer() {
for (auto& task : _commTasks) {
unregisterChunkedTask(task);
_scheduler->destroyTask(task);
}
stopListening();
}
HttpServer::~HttpServer() { stopListening(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief generates a suitable communication task
@ -122,7 +90,6 @@ HttpCommTask* HttpServer::createCommTask(TRI_socket_t s,
return new HttpCommTask(this, s, info, _keepAliveTimeout);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add the endpoint list
////////////////////////////////////////////////////////////////////////////////
@ -167,28 +134,6 @@ void HttpServer::stopListening() {
_listenTasks.clear();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief registers a chunked task
////////////////////////////////////////////////////////////////////////////////
void HttpServer::registerChunkedTask(HttpCommTask* task) {
auto id = task->taskId();
MUTEX_LOCKER(HttpCommTaskMapLock);
HttpCommTaskMap[id] = task;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief unregisters a chunked task
////////////////////////////////////////////////////////////////////////////////
void HttpServer::unregisterChunkedTask(HttpCommTask* task) {
auto id = task->taskId();
MUTEX_LOCKER(HttpCommTaskMapLock);
HttpCommTaskMap.erase(id);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief removes all listen and comm tasks
////////////////////////////////////////////////////////////////////////////////
@ -208,7 +153,6 @@ void HttpServer::stop() {
_commTasks.erase(task);
}
unregisterChunkedTask(task);
_scheduler->destroyTask(task);
}
}
@ -239,12 +183,8 @@ void HttpServer::handleConnected(TRI_socket_t s, ConnectionInfo const& info) {
////////////////////////////////////////////////////////////////////////////////
void HttpServer::handleCommunicationClosed(HttpCommTask* task) {
{
MUTEX_LOCKER(_commTasksLock);
_commTasks.erase(task);
}
unregisterChunkedTask(task);
MUTEX_LOCKER(_commTasksLock);
_commTasks.erase(task);
}
////////////////////////////////////////////////////////////////////////////////
@ -252,12 +192,8 @@ void HttpServer::handleCommunicationClosed(HttpCommTask* task) {
////////////////////////////////////////////////////////////////////////////////
void HttpServer::handleCommunicationFailure(HttpCommTask* task) {
{
MUTEX_LOCKER(_commTasksLock);
_commTasks.erase(task);
}
unregisterChunkedTask(task);
MUTEX_LOCKER(_commTasksLock);
_commTasks.erase(task);
}
////////////////////////////////////////////////////////////////////////////////
@ -325,7 +261,6 @@ bool HttpServer::handleRequest(HttpCommTask* task,
return res == TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief opens a listen port
////////////////////////////////////////////////////////////////////////////////
@ -344,7 +279,7 @@ bool HttpServer::openEndpoint(Endpoint* endpoint) {
}
int res = _scheduler->registerTask(task);
if (res == TRI_ERROR_NO_ERROR) {
_listenTasks.emplace_back(task);
return true;
@ -359,8 +294,16 @@ bool HttpServer::openEndpoint(Endpoint* endpoint) {
void HttpServer::handleRequestDirectly(HttpCommTask* task,
HttpHandler* handler) {
handler->executeFull();
task->handleResponse(handler->getResponse());
HttpHandler::status_t status = handler->executeFull();
switch (status._status) {
case HttpHandler::HANDLER_FAILED:
case HttpHandler::HANDLER_DONE:
task->handleResponse(handler->getResponse());
break;
case HttpHandler::HANDLER_ASYNC:
// do nothing, just wait
break;
}
}

View File

@ -142,18 +142,6 @@ class HttpServer : protected TaskManager {
void stopListening();
//////////////////////////////////////////////////////////////////////////////
/// @brief registers a chunked task
//////////////////////////////////////////////////////////////////////////////
void registerChunkedTask(HttpCommTask*);
//////////////////////////////////////////////////////////////////////////////
/// @brief unregisters a chunked task
//////////////////////////////////////////////////////////////////////////////
void unregisterChunkedTask(HttpCommTask*);
//////////////////////////////////////////////////////////////////////////////
/// @brief removes all listen and comm tasks
//////////////////////////////////////////////////////////////////////////////

View File

@ -37,8 +37,6 @@ using namespace arangodb;
using namespace triagens::rest;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new server job
////////////////////////////////////////////////////////////////////////////////
@ -62,7 +60,6 @@ HttpServerJob::~HttpServerJob() {
}
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -134,5 +131,3 @@ void HttpServerJob::cleanup(DispatcherQueue* queue) {
void HttpServerJob::handleError(triagens::basics::Exception const& ex) {
_handler->handleError(ex);
}

View File

@ -150,6 +150,7 @@ arangod_libarangod_a_SOURCES = \
arangod/RestHandler/RestUploadHandler.cpp \
arangod/RestHandler/RestVersionHandler.cpp \
arangod/RestHandler/RestVocbaseBaseHandler.cpp \
arangod/RestHandler/WorkMonitorHandler.cpp \
arangod/RestServer/ArangoServer.cpp \
arangod/RestServer/ConsoleThread.cpp \
arangod/RestServer/VocbaseContext.cpp \

View File

@ -22,14 +22,16 @@
////////////////////////////////////////////////////////////////////////////////
#include "RestVersionHandler.h"
#include "Rest/AnyServer.h"
#include "Rest/HttpRequest.h"
#include "Rest/Version.h"
using namespace arangodb;
using namespace triagens::basics;
using namespace triagens::rest;
using namespace triagens::admin;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// @brief ArangoDB server
@ -37,12 +39,13 @@ using namespace std;
extern AnyServer* ArangoInstance;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestVersionHandler::RestVersionHandler(HttpRequest* request)
: RestBaseHandler(request) {}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -50,7 +53,7 @@ RestVersionHandler::RestVersionHandler(HttpRequest* request)
bool RestVersionHandler::isDirect() const { return true; }
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock JSF_get_api_return
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
HttpHandler::status_t RestVersionHandler::execute() {
@ -81,5 +84,3 @@ HttpHandler::status_t RestVersionHandler::execute() {
}
return status_t(HANDLER_DONE);
}

View File

@ -24,25 +24,22 @@
#ifndef ARANGOD_REST_HANDLER_REST_VERSION_HANDLER_H
#define ARANGOD_REST_HANDLER_REST_VERSION_HANDLER_H 1
#include "Basics/Common.h"
#include "Rest/HttpResponse.h"
#include "RestHandler/RestBaseHandler.h"
namespace triagens {
namespace admin {
namespace arangodb {
////////////////////////////////////////////////////////////////////////////////
/// @brief version request handler
////////////////////////////////////////////////////////////////////////////////
class RestVersionHandler : public RestBaseHandler {
class RestVersionHandler : public triagens::admin::RestBaseHandler {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
explicit RestVersionHandler(rest::HttpRequest*);
explicit RestVersionHandler(triagens::rest::HttpRequest*);
public:
//////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
@ -51,14 +48,11 @@ class RestVersionHandler : public RestBaseHandler {
bool isDirect() const override;
//////////////////////////////////////////////////////////////////////////////
/// @brief returns the server version number
/// {@inheritDoc}
//////////////////////////////////////////////////////////////////////////////
status_t execute() override;
};
}
}
#endif

View File

@ -0,0 +1,56 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016-2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#include "WorkMonitorHandler.h"
#include "HttpServer/HttpHandler.h"
#include "Rest/HttpRequest.h"
using namespace arangodb;
using namespace triagens::basics;
using triagens::rest::HttpRequest;
using triagens::rest::HttpHandler;
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
WorkMonitorHandler::WorkMonitorHandler(HttpRequest* request)
: RestBaseHandler(request) {}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool WorkMonitorHandler::isDirect() const { return true; }
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
HttpHandler::status_t WorkMonitorHandler::execute() {
WorkMonitor::requestWorkOverview(_taskId);
return status_t(HANDLER_ASYNC);
}

View File

@ -0,0 +1,57 @@
////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2016-2016 ArangoDB GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGOD_REST_HANDLER_WORK_MONITOR_HANDLER_H
#define ARANGOD_REST_HANDLER_WORK_MONITOR_HANDLER_H 1
#include "RestHandler/RestBaseHandler.h"
namespace arangodb {
////////////////////////////////////////////////////////////////////////////////
/// @brief version request handler
////////////////////////////////////////////////////////////////////////////////
class WorkMonitorHandler : public triagens::admin::RestBaseHandler {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
explicit WorkMonitorHandler(triagens::rest::HttpRequest*);
public:
//////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
//////////////////////////////////////////////////////////////////////////////
bool isDirect() const override;
//////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
//////////////////////////////////////////////////////////////////////////////
status_t execute() override;
};
}
#endif

View File

@ -75,6 +75,7 @@
#include "RestHandler/RestSimpleQueryHandler.h"
#include "RestHandler/RestUploadHandler.h"
#include "RestHandler/RestVersionHandler.h"
#include "RestHandler/WorkMonitorHandler.h"
#include "RestServer/ConsoleThread.h"
#include "RestServer/VocbaseContext.h"
#include "Scheduler/ApplicationScheduler.h"
@ -224,7 +225,7 @@ void ArangoServer::defineHandlers(HttpHandlerFactory* factory) {
factory->addHandler(
"/_api/version",
RestHandlerCreator<triagens::admin::RestVersionHandler>::createNoData,
RestHandlerCreator<RestVersionHandler>::createNoData,
nullptr);
factory->addHandler(
@ -241,7 +242,7 @@ void ArangoServer::defineHandlers(HttpHandlerFactory* factory) {
factory->addHandler(
"/_admin/version",
RestHandlerCreator<triagens::admin::RestVersionHandler>::createNoData,
RestHandlerCreator<RestVersionHandler>::createNoData,
nullptr);
factory->addHandler(
@ -255,6 +256,11 @@ void ArangoServer::defineHandlers(HttpHandlerFactory* factory) {
RestHandlerCreator<triagens::admin::RestAdminLogHandler>::createNoData,
nullptr);
factory->addHandler(
"/_admin/work-monitor",
RestHandlerCreator<WorkMonitorHandler>::createNoData,
nullptr);
factory->addPrefixHandler(
"/_admin/shutdown",
RestHandlerCreator<triagens::admin::RestShutdownHandler>::createData<

View File

@ -437,6 +437,21 @@ Task* Scheduler::lookupTaskById(uint64_t taskId) {
return task->second;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the loop for a task id
////////////////////////////////////////////////////////////////////////////////
size_t Scheduler::lookupLoopById(uint64_t taskId) {
MUTEX_LOCKER(schedulerLock);
auto&& task = taskRegistered.find(taskId);
if (task == taskRegistered.end()) {
return nrThreads;
}
return task->second->eventLoop();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief registers a new task

View File

@ -32,7 +32,6 @@
#include "Basics/Mutex.h"
struct TRI_json_t;
namespace triagens {
@ -44,7 +43,6 @@ namespace rest {
class SchedulerThread;
class TaskData;
////////////////////////////////////////////////////////////////////////////////
/// @brief input-output scheduler
////////////////////////////////////////////////////////////////////////////////
@ -53,7 +51,6 @@ class Scheduler : private TaskManager {
Scheduler(Scheduler const&) = delete;
Scheduler& operator=(Scheduler const&) = delete;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief scheduler singleton
@ -61,7 +58,6 @@ class Scheduler : private TaskManager {
static std::unique_ptr<Scheduler> SCHEDULER;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
@ -79,10 +75,8 @@ class Scheduler : private TaskManager {
explicit Scheduler(size_t nrThreads);
virtual ~Scheduler();
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief starts scheduler, keeps running
@ -212,13 +206,17 @@ class Scheduler : private TaskManager {
/// @brief returns the task for a task id
///
/// Warning: ONLY call this from within the scheduler task! Otherwise, the
/// task
/// MIGHT already be deleted.
/// task MIGHT already be deleted.
//////////////////////////////////////////////////////////////////////////////
Task* lookupTaskById(uint64_t);
//////////////////////////////////////////////////////////////////////////////
/// @brief returns the loop for a task id
//////////////////////////////////////////////////////////////////////////////
size_t lookupLoopById(uint64_t);
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief main event loop
@ -300,7 +298,6 @@ class Scheduler : private TaskManager {
virtual void signalTask(std::unique_ptr<TaskData>&) = 0;
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief registers a new task
@ -316,7 +313,6 @@ class Scheduler : private TaskManager {
int checkInsertTask(Task const*);
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief number of scheduler threads
@ -330,7 +326,6 @@ class Scheduler : private TaskManager {
SchedulerThread** threads;
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief initializes the signal handlers for the scheduler
@ -338,7 +333,6 @@ class Scheduler : private TaskManager {
static void initializeSignalHandlers();
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief true if scheduler is shutting down
@ -386,5 +380,3 @@ class Scheduler : private TaskManager {
}
#endif

View File

@ -30,13 +30,11 @@
using namespace triagens::rest;
using namespace std;
namespace {
std::atomic_uint_fast64_t NEXT_TASK_ID(static_cast<uint64_t>(TRI_microtime() *
100000.0));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new task
////////////////////////////////////////////////////////////////////////////////
@ -60,7 +58,6 @@ Task::Task(std::string const& name) : Task("", name) {}
Task::~Task() {}
////////////////////////////////////////////////////////////////////////////////
/// @brief get a JSON representation of the task
////////////////////////////////////////////////////////////////////////////////
@ -97,12 +94,9 @@ bool Task::isUserDefined() const { return false; }
bool Task::needsMainEventLoop() const { return false; }
////////////////////////////////////////////////////////////////////////////////
/// @brief get a task specific description in JSON format
/// this does nothing for basic tasks, but derived classes may override it
////////////////////////////////////////////////////////////////////////////////
void Task::getDescription(TRI_json_t* json) const {}

View File

@ -38,7 +38,6 @@ namespace rest {
class Scheduler;
class HttpResponse;
class TaskData : public RequestStatisticsAgent {
public:
static uint64_t const TASK_DATA_RESPONSE = 1000;
@ -52,7 +51,6 @@ class TaskData : public RequestStatisticsAgent {
std::unique_ptr<HttpResponse> _response;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief abstract base class for tasks
////////////////////////////////////////////////////////////////////////////////
@ -63,7 +61,6 @@ class Task {
friend class TaskManager;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new task
@ -95,7 +92,6 @@ class Task {
virtual ~Task();
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief returns the task name for debugging
@ -154,7 +150,6 @@ class Task {
virtual void signalTask(TaskData*) {}
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief get a task specific description in JSON format
@ -180,7 +175,6 @@ class Task {
virtual void cleanup() = 0;
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief scheduler
@ -200,7 +194,6 @@ class Task {
EventLoop _loop;
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief task id
@ -218,4 +211,3 @@ class Task {
}
#endif

View File

@ -22,7 +22,11 @@
////////////////////////////////////////////////////////////////////////////////
#include "Basics/WorkMonitor.h"
#include "Basics/StringBuffer.h"
#include "HttpServer/HttpHandler.h"
#include "Scheduler/Scheduler.h"
#include "Scheduler/Task.h"
#include <velocypack/Builder.h>
#include <velocypack/Value.h>
@ -31,26 +35,6 @@
using namespace arangodb;
using namespace triagens::rest;
HandlerWorkStack::HandlerWorkStack(HttpHandler* handler) : _handler(handler) {
WorkMonitor::pushHandler(_handler);
}
HandlerWorkStack::HandlerWorkStack(WorkItem::uptr<HttpHandler>& handler) {
_handler = handler.release();
WorkMonitor::pushHandler(_handler);
}
HandlerWorkStack::~HandlerWorkStack() {
WorkMonitor::popHandler(_handler, true);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief pushes a handler
////////////////////////////////////////////////////////////////////////////////
@ -99,7 +83,7 @@ void WorkMonitor::DELETE_HANDLER(WorkDescription* desc) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief thread description string
/// @brief thread description
////////////////////////////////////////////////////////////////////////////////
void WorkMonitor::VPACK_HANDLER(VPackBuilder* b, WorkDescription* desc) {
@ -138,4 +122,49 @@ void WorkMonitor::VPACK_HANDLER(VPackBuilder* b, WorkDescription* desc) {
b->close();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sends the overview
////////////////////////////////////////////////////////////////////////////////
void WorkMonitor::SEND_WORK_OVERVIEW(uint64_t taskId, std::string const& data) {
auto response = std::make_unique<HttpResponse>(HttpResponse::OK,
HttpRequest::MinCompatibility);
response->setContentType("application/json; charset=utf-8");
TRI_AppendString2StringBuffer(response->body().stringBuffer(), data.c_str(),
data.length());
auto answer = std::make_unique<TaskData>();
answer->_taskId = taskId;
answer->_loop = Scheduler::SCHEDULER->lookupLoopById(taskId);
answer->_type = TaskData::TASK_DATA_RESPONSE;
answer->_response.reset(response.release());
Scheduler::SCHEDULER->signalTask(answer);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
HandlerWorkStack::HandlerWorkStack(HttpHandler* handler) : _handler(handler) {
WorkMonitor::pushHandler(_handler);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
HandlerWorkStack::HandlerWorkStack(WorkItem::uptr<HttpHandler>& handler) {
_handler = handler.release();
WorkMonitor::pushHandler(_handler);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
HandlerWorkStack::~HandlerWorkStack() {
WorkMonitor::popHandler(_handler, true);
}

View File

@ -30,7 +30,6 @@
#include <sstream>
////////////////////////////////////////////////////////////////////////////////
/// @brief string buffer with formatting routines
////////////////////////////////////////////////////////////////////////////////
@ -42,7 +41,6 @@ typedef struct TRI_string_buffer_s {
size_t _len;
} TRI_string_buffer_t;
////////////////////////////////////////////////////////////////////////////////
/// @brief create a new string buffer and initialize it
////////////////////////////////////////////////////////////////////////////////
@ -94,7 +92,6 @@ void TRI_AnnihilateStringBuffer(TRI_string_buffer_t*);
void TRI_FreeStringBuffer(TRI_memory_zone_t*, TRI_string_buffer_t*);
////////////////////////////////////////////////////////////////////////////////
/// @brief compress the string buffer using deflate
////////////////////////////////////////////////////////////////////////////////
@ -186,8 +183,6 @@ void TRI_MoveFrontStringBuffer(TRI_string_buffer_t*, size_t);
int TRI_ReplaceStringStringBuffer(TRI_string_buffer_t*, char const*, size_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends character
////////////////////////////////////////////////////////////////////////////////
@ -228,8 +223,6 @@ int TRI_AppendJsonEncodedStringStringBuffer(TRI_string_buffer_t* self,
int TRI_AppendJsonEncodedStringStringBuffer(TRI_string_buffer_t* self,
char const* str, size_t, bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends integer with two digits
////////////////////////////////////////////////////////////////////////////////
@ -296,8 +289,6 @@ int TRI_AppendInt64StringBuffer(TRI_string_buffer_t* self, int64_t attr);
int TRI_AppendUInt64StringBuffer(TRI_string_buffer_t* self, uint64_t attr);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends unsigned integer with 32 bits in octal
////////////////////////////////////////////////////////////////////////////////
@ -310,8 +301,6 @@ int TRI_AppendUInt32OctalStringBuffer(TRI_string_buffer_t* self, uint32_t attr);
int TRI_AppendUInt64OctalStringBuffer(TRI_string_buffer_t* self, uint64_t attr);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends unsigned integer with 32 bits in hex
////////////////////////////////////////////////////////////////////////////////
@ -324,24 +313,18 @@ int TRI_AppendUInt32HexStringBuffer(TRI_string_buffer_t* self, uint32_t attr);
int TRI_AppendUInt64HexStringBuffer(TRI_string_buffer_t* self, uint64_t attr);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends floating point number with 8 bits
////////////////////////////////////////////////////////////////////////////////
int TRI_AppendDoubleStringBuffer(TRI_string_buffer_t* self, double attr);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends time in standard format
////////////////////////////////////////////////////////////////////////////////
int TRI_AppendTimeStringBuffer(TRI_string_buffer_t* self, int32_t attr);
////////////////////////////////////////////////////////////////////////////////
/// @brief appends csv 32-bit integer
////////////////////////////////////////////////////////////////////////////////
@ -372,7 +355,6 @@ int TRI_AppendCsvUInt64StringBuffer(TRI_string_buffer_t* self, uint64_t i);
int TRI_AppendCsvDoubleStringBuffer(TRI_string_buffer_t* self, double d);
// -----------------------------------------------------------------------------
// string buffer with formatting routines
// -----------------------------------------------------------------------------
@ -386,7 +368,6 @@ int TRI_AppendCsvDoubleStringBuffer(TRI_string_buffer_t* self, double d);
namespace triagens {
namespace basics {
////////////////////////////////////////////////////////////////////////////////
/// @brief string buffer with formatting routines
////////////////////////////////////////////////////////////////////////////////
@ -397,7 +378,6 @@ class StringBuffer {
StringBuffer(StringBuffer const&) = delete;
StringBuffer& operator=(StringBuffer const&) = delete;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief initializes the string buffer
@ -435,7 +415,6 @@ class StringBuffer {
return TRI_ReserveStringBuffer(&_buffer, length);
}
//////////////////////////////////////////////////////////////////////////////
/// @brief compress the buffer using deflate
//////////////////////////////////////////////////////////////////////////////
@ -767,8 +746,6 @@ class StringBuffer {
_buffer._len = other->_len;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief appends character
//////////////////////////////////////////////////////////////////////////////
@ -832,8 +809,6 @@ class StringBuffer {
return *this;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief appends integer with two digits
//////////////////////////////////////////////////////////////////////////////
@ -963,8 +938,6 @@ class StringBuffer {
#endif
//////////////////////////////////////////////////////////////////////////////
/// @brief appends unsigned integer with 32 bits in octal
//////////////////////////////////////////////////////////////////////////////
@ -995,8 +968,6 @@ class StringBuffer {
#endif
//////////////////////////////////////////////////////////////////////////////
/// @brief appends unsigned integer with 32 bits in hex
//////////////////////////////////////////////////////////////////////////////
@ -1025,8 +996,6 @@ class StringBuffer {
#endif
//////////////////////////////////////////////////////////////////////////////
/// @brief appends floating point number with 8 bits
//////////////////////////////////////////////////////////////////////////////
@ -1036,8 +1005,6 @@ class StringBuffer {
return *this;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief appends time in standard format
///
@ -1049,8 +1016,6 @@ class StringBuffer {
return *this;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief appends csv string
//////////////////////////////////////////////////////////////////////////////
@ -1109,7 +1074,6 @@ class StringBuffer {
return *this;
}
//////////////////////////////////////////////////////////////////////////////
/// @brief underlying C string buffer
//////////////////////////////////////////////////////////////////////////////
@ -1120,5 +1084,3 @@ class StringBuffer {
}
#endif

View File

@ -36,23 +36,6 @@
using namespace arangodb;
using namespace triagens::basics;
CustomWorkStack::CustomWorkStack(char const* type, char const* text,
size_t length) {
WorkMonitor::pushCustom(type, text, length);
}
CustomWorkStack::CustomWorkStack(char const* type, uint64_t id) {
WorkMonitor::pushCustom(type, id);
}
CustomWorkStack::~CustomWorkStack() { WorkMonitor::popCustom(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief singleton
////////////////////////////////////////////////////////////////////////////////
@ -95,13 +78,18 @@ static boost::lockfree::queue<WorkDescription*> EMPTY_WORK_DESCRIPTION(128);
static boost::lockfree::queue<WorkDescription*> FREEABLE_WORK_DESCRIPTION(128);
////////////////////////////////////////////////////////////////////////////////
/// @brief tasks that want an overview
////////////////////////////////////////////////////////////////////////////////
static boost::lockfree::queue<uint64_t> WORK_OVERVIEW(128);
////////////////////////////////////////////////////////////////////////////////
/// @brief stopped flag
////////////////////////////////////////////////////////////////////////////////
static std::atomic<bool> WORK_MONITOR_STOPPED(true);
////////////////////////////////////////////////////////////////////////////////
/// @brief deletes a description and its resources
////////////////////////////////////////////////////////////////////////////////
@ -136,11 +124,6 @@ static void deleteWorkDescription(WorkDescription* desc, bool stopped) {
/// @brief vpack representation of a work description
////////////////////////////////////////////////////////////////////////////////
#undef SHOW_RESULTS
// TODO(fc) use vpackWorkDescription
#ifdef SHOW_RESULTS
#include <iostream>
static void vpackWorkDescription(VPackBuilder* b, WorkDescription* desc) {
switch (desc->_type) {
case WorkType::THREAD:
@ -168,23 +151,19 @@ static void vpackWorkDescription(VPackBuilder* b, WorkDescription* desc) {
}
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
WorkDescription::WorkDescription(WorkType type, WorkDescription* prev)
: _type(type), _destroy(true), _prev(prev) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructors a new monitor
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
WorkMonitor::WorkMonitor() : Thread("Work Monitor"), _stopping(false) {}
////////////////////////////////////////////////////////////////////////////////
/// @brief creates an empty WorkDescription
////////////////////////////////////////////////////////////////////////////////
@ -354,6 +333,13 @@ void WorkMonitor::popCustom() {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief requests a work overview
////////////////////////////////////////////////////////////////////////////////
void WorkMonitor::requestWorkOverview(uint64_t taskId) {
WORK_OVERVIEW.push(taskId);
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
@ -364,10 +350,6 @@ void WorkMonitor::run() {
const uint32_t minSleep = 100;
uint32_t s = minSleep;
#ifdef SHOW_RESULTS
double x = 0;
#endif
// clean old entries and create summary if requested
while (!_stopping) {
try {
@ -387,27 +369,29 @@ void WorkMonitor::run() {
s *= 2;
}
// TODO(fc) trigger output
#ifdef SHOW_RESULTS
double y = TRI_microtime();
uint64_t taskId;
if (x + 10 < y) {
x = y;
MutexLocker guard(&THREADS_LOCK);
while (WORK_OVERVIEW.pop(taskId)) {
VPackBuilder b;
b.add(VPackValue(VPackValueType::Array));
for (auto& thread : THREADS) {
WorkDescription* desc = thread->workDescription();
b.add(VPackValue(VPackValueType::Object));
b.add("work", VPackValue(VPackValueType::Array));
if (desc != nullptr) {
b.add(VPackValue(VPackValueType::Object));
vpackWorkDescription(&b, desc);
b.close();
{
MutexLocker guard(&THREADS_LOCK);
for (auto& thread : THREADS) {
WorkDescription* desc = thread->workDescription();
if (desc != nullptr) {
b.add(VPackValue(VPackValueType::Object));
vpackWorkDescription(&b, desc);
b.close();
}
}
}
b.close();
b.close();
VPackSlice s(b.start());
@ -421,9 +405,8 @@ void WorkMonitor::run() {
VPackDumper dumper(&sink, &options);
dumper.dump(s);
std::cout << buffer << "\n";
SEND_WORK_OVERVIEW(taskId, buffer);
}
#endif
} catch (...) {
// must prevent propagation of exceptions from here
}
@ -451,6 +434,28 @@ void WorkMonitor::run() {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
CustomWorkStack::CustomWorkStack(char const* type, char const* text,
size_t length) {
WorkMonitor::pushCustom(type, text, length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
CustomWorkStack::CustomWorkStack(char const* type, uint64_t id) {
WorkMonitor::pushCustom(type, id);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
CustomWorkStack::~CustomWorkStack() { WorkMonitor::popCustom(); }
////////////////////////////////////////////////////////////////////////////////
/// @brief starts the work monitor
@ -469,5 +474,3 @@ void arangodb::ShutdownWorkMonitor() {
WORK_MONITOR.shutdown();
WORK_MONITOR.join();
}

View File

@ -28,7 +28,6 @@
#include "Basics/WorkItem.h"
namespace triagens {
namespace rest {
class HttpHandler;
@ -40,14 +39,12 @@ namespace velocypack {
class Builder;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief type of the current work
////////////////////////////////////////////////////////////////////////////////
enum class WorkType { THREAD, HANDLER, CUSTOM };
////////////////////////////////////////////////////////////////////////////////
/// @brief description of the current work
////////////////////////////////////////////////////////////////////////////////
@ -72,21 +69,18 @@ struct WorkDescription {
WorkDescription* _prev;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief work monitor class
////////////////////////////////////////////////////////////////////////////////
class WorkMonitor : public triagens::basics::Thread {
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructors a new monitor
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
WorkMonitor();
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief creates an empty WorkDescription
@ -129,7 +123,11 @@ class WorkMonitor : public triagens::basics::Thread {
//////////////////////////////////////////////////////////////////////////////
static void pushCustom(char const* type, char const* text, size_t length);
//////////////////////////////////////////////////////////////////////////////
/// @brief pushes a custom task
//////////////////////////////////////////////////////////////////////////////
static void pushCustom(char const* type, uint64_t id);
//////////////////////////////////////////////////////////////////////////////
@ -157,13 +155,24 @@ class WorkMonitor : public triagens::basics::Thread {
static void DELETE_HANDLER(WorkDescription* desc);
//////////////////////////////////////////////////////////////////////////////
/// @brief handler description string
/// @brief requests a work overview
//////////////////////////////////////////////////////////////////////////////
static void requestWorkOverview(uint64_t taskId);
//////////////////////////////////////////////////////////////////////////////
/// @brief handler description
//////////////////////////////////////////////////////////////////////////////
static void VPACK_HANDLER(arangodb::velocypack::Builder*,
WorkDescription* desc);
//////////////////////////////////////////////////////////////////////////////
/// @brief sends the overview
//////////////////////////////////////////////////////////////////////////////
static void SEND_WORK_OVERVIEW(uint64_t, std::string const&);
protected:
//////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
@ -171,7 +180,6 @@ class WorkMonitor : public triagens::basics::Thread {
void run() override;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief initiate shutdown
@ -179,7 +187,6 @@ class WorkMonitor : public triagens::basics::Thread {
void shutdown() { _stopping = true; }
//////////////////////////////////////////////////////////////////////////////
/// @brief stopping flag
//////////////////////////////////////////////////////////////////////////////
@ -187,7 +194,6 @@ class WorkMonitor : public triagens::basics::Thread {
std::atomic<bool> _stopping;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief auto push and pop for HttpHandler
////////////////////////////////////////////////////////////////////////////////
@ -196,18 +202,25 @@ class HandlerWorkStack {
HandlerWorkStack(const HandlerWorkStack&) = delete;
HandlerWorkStack& operator=(const HandlerWorkStack&) = delete;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
explicit HandlerWorkStack(triagens::rest::HttpHandler*);
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
explicit HandlerWorkStack(WorkItem::uptr<triagens::rest::HttpHandler>&);
//////////////////////////////////////////////////////////////////////////////
/// @brief destructor
//////////////////////////////////////////////////////////////////////////////
~HandlerWorkStack();
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief returns the handler
@ -215,7 +228,6 @@ class HandlerWorkStack {
triagens::rest::HttpHandler* handler() const { return _handler; }
private:
//////////////////////////////////////////////////////////////////////////////
/// @brief handler
@ -224,27 +236,34 @@ class HandlerWorkStack {
triagens::rest::HttpHandler* _handler;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief auto push and pop for HttpHandler
/// @brief auto push and pop for Custom
////////////////////////////////////////////////////////////////////////////////
class CustomWorkStack {
CustomWorkStack(const CustomWorkStack&) = delete;
CustomWorkStack& operator=(const CustomWorkStack&) = delete;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
CustomWorkStack(char const* type, char const* text, size_t length);
//////////////////////////////////////////////////////////////////////////////
/// @brief constructor
//////////////////////////////////////////////////////////////////////////////
CustomWorkStack(char const* type, uint64_t id);
//////////////////////////////////////////////////////////////////////////////
/// @brief destructor
//////////////////////////////////////////////////////////////////////////////
~CustomWorkStack();
};
////////////////////////////////////////////////////////////////////////////////
/// @brief starts the work monitor
////////////////////////////////////////////////////////////////////////////////
@ -259,5 +278,3 @@ void ShutdownWorkMonitor();
}
#endif

View File

@ -28,8 +28,6 @@
using namespace arangodb;
////////////////////////////////////////////////////////////////////////////////
/// @brief thread deleter
////////////////////////////////////////////////////////////////////////////////
@ -44,4 +42,10 @@ void WorkMonitor::VPACK_HANDLER(VPackBuilder*, WorkDescription*) {
TRI_ASSERT(false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief sends the overview
////////////////////////////////////////////////////////////////////////////////
void WorkMonitor::SEND_WORK_OVERVIEW(uint64_t, std::string const&) {
TRI_ASSERT(false);
}

View File

@ -31,7 +31,6 @@ using namespace triagens::basics;
using namespace triagens::rest;
using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// @brief batch error count header
////////////////////////////////////////////////////////////////////////////////
@ -179,7 +178,8 @@ std::string HttpResponse::responseString(HttpResponseCode code) {
/// @brief get http response code from string
////////////////////////////////////////////////////////////////////////////////
HttpResponse::HttpResponseCode HttpResponse::responseCode(std::string const& str) {
HttpResponse::HttpResponseCode HttpResponse::responseCode(
std::string const& str) {
int number = ::atoi(str.c_str());
switch (number) {
@ -432,7 +432,6 @@ HttpResponse::HttpResponseCode HttpResponse::responseCode(int code) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new http response
////////////////////////////////////////////////////////////////////////////////
@ -464,7 +463,6 @@ HttpResponse::~HttpResponse() {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the response code
////////////////////////////////////////////////////////////////////////////////
@ -560,7 +558,7 @@ std::string HttpResponse::header(std::string const& key, bool& found) const {
////////////////////////////////////////////////////////////////////////////////
std::string HttpResponse::header(char const* key, size_t keyLength,
bool& found) const {
bool& found) const {
Dictionary<char const*>::KeyValue const* kv = _headers.lookup(key, keyLength);
if (kv == nullptr) {
@ -1006,7 +1004,6 @@ int HttpResponse::deflate(size_t bufferSize) {
return TRI_ERROR_NO_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief checks for special headers
////////////////////////////////////////////////////////////////////////////////
@ -1020,5 +1017,3 @@ void HttpResponse::checkHeader(char const* key, char const* value) {
}
}
}

View File

@ -30,7 +30,6 @@
#include "Basics/Dictionary.h"
#include "Basics/StringBuffer.h"
namespace triagens {
namespace rest {
@ -46,7 +45,6 @@ class HttpResponse {
HttpResponse(HttpResponse const&) = delete;
HttpResponse& operator=(HttpResponse const&) = delete;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief http response codes
@ -105,7 +103,6 @@ class HttpResponse {
NOT_EXTENDED = 510
};
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the response is a HTTP HEAD response
@ -136,7 +133,6 @@ class HttpResponse {
static HttpResponseCode responseCode(int);
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new http response
@ -153,7 +149,6 @@ class HttpResponse {
~HttpResponse();
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief returns the response code
@ -330,14 +325,12 @@ class HttpResponse {
int deflate(size_t = 16384);
//////////////////////////////////////////////////////////////////////////////
/// @brief checks for special headers
//////////////////////////////////////////////////////////////////////////////
void checkHeader(char const* key, char const* value);
protected:
//////////////////////////////////////////////////////////////////////////////
/// @brief response code
@ -393,7 +386,6 @@ class HttpResponse {
std::vector<char const*> _freeables;
public:
//////////////////////////////////////////////////////////////////////////////
/// @brief batch error count header
@ -401,9 +393,9 @@ class HttpResponse {
static std::string const BatchErrorHeader;
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock serverHideProductHeader
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief was docuBlock serverHideProductHeader
////////////////////////////////////////////////////////////////////////////////
static bool HideProductHeader;
};
@ -411,5 +403,3 @@ class HttpResponse {
}
#endif