1
0
Fork 0

added cancelation of asnyc jobs

Conflicts:
	arangod/V8Server/ApplicationV8.cpp
	arangod/V8Server/v8-actions.cpp
	lib/Rest/Handler.h
This commit is contained in:
Frank Celler 2014-04-07 16:51:59 +02:00
parent 39fd596abc
commit 8e9ad58f3b
41 changed files with 683 additions and 475 deletions

View File

@ -95,6 +95,10 @@ Managing Async Results via HTTP {#HttpJobHttp}
@anchor HttpJobPut
@copydetails triagens::admin::RestJobHandler::putJob
@CLEARPAGE
@anchor HttpJobPutMethod
@copydetails triagens::admin::RestJobHandler::putJobMethod
@CLEARPAGE
@anchor HttpJobDelete
@copydetails triagens::admin::RestJobHandler::deleteJob

View File

@ -9,6 +9,7 @@ TOC {#HttpJobTOC}
- @ref HttpJobOrder
- @ref HttpJobHttp
- @ref HttpJobPut "PUT /_api/job/job-id"
- @ref HttpJobPutMethod "PUT /_api/job/cancel/job-id"
- @ref HttpJobDelete "DELETE /_api/job/job-id"
- @ref HttpJobGetId "GET /_api/job/job-id"
- @ref HttpJobGetType "GET /_api/job/job-type"

View File

@ -49,7 +49,9 @@ RestActionHandler::RestActionHandler (HttpRequest* request,
: RestVocbaseBaseHandler(request),
_action(0),
_queue(),
_allowed(false) {
_allowed(false),
_dataLock(),
_data(0) {
_action = TRI_LookupActionVocBase(request);
@ -72,8 +74,8 @@ RestActionHandler::RestActionHandler (HttpRequest* request,
_queue = data->_queue;
}
// must have a queue
if (_queue.empty()) {
// must have a queue
_queue = "STANDARD";
}
}
@ -158,6 +160,20 @@ HttpHandler::status_t RestActionHandler::execute () {
}
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool RestActionHandler::cancel (bool running) {
if (running) {
return _action->cancel(&_dataLock, &_data);
}
else {
generateCanceled();
return true;
}
}
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
@ -167,11 +183,15 @@ HttpHandler::status_t RestActionHandler::execute () {
////////////////////////////////////////////////////////////////////////////////
TRI_action_result_t RestActionHandler::executeAction () {
TRI_action_result_t result = _action->execute(_vocbase, _request);
TRI_action_result_t result = _action->execute(_vocbase, _request, &_dataLock, &_data);
if (result.isValid) {
_response = result.response;
}
else if (result.canceled) {
result.isValid = true;
generateCanceled();
}
else {
result.isValid = true;
generateNotImplemented(_action->_url);

View File

@ -105,6 +105,12 @@ namespace triagens {
status_t execute ();
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool cancel (bool running);
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
@ -140,6 +146,19 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
bool _allowed;
////////////////////////////////////////////////////////////////////////////////
/// @brief data lock
////////////////////////////////////////////////////////////////////////////////
basics::Mutex _dataLock;
////////////////////////////////////////////////////////////////////////////////
/// @brief data for cancelation
////////////////////////////////////////////////////////////////////////////////
void* _data;
};
}
}

View File

@ -29,6 +29,7 @@
#define TRIAGENS_ACTIONS_ACTIONS_H 1
#include "Basics/Common.h"
#include "Basics/Mutex.h"
// -----------------------------------------------------------------------------
// --SECTION-- forward declarations
@ -54,7 +55,7 @@ namespace triagens {
class TRI_action_result_t {
public:
TRI_action_result_t ()
: isValid(false), requeue(false), response(0), sleep(0.0) {
: isValid(false), requeue(false), canceled(false), response(0), sleep(0.0) {
}
// Please be careful here: In the beginning we had "bool requeue" after
@ -65,8 +66,10 @@ class TRI_action_result_t {
// In this order it seems to work.
// Details: v8-actions.cpp: v8_action_t::execute returns a TRI_action_result_t
// to RestActionHandler::executeAction and suddenly requeue is true.
bool isValid;
bool requeue;
bool canceled;
triagens::rest::HttpResponse* response;
@ -85,7 +88,13 @@ class TRI_action_t {
virtual ~TRI_action_t () {}
virtual TRI_action_result_t execute (struct TRI_vocbase_s*, triagens::rest::HttpRequest*) = 0;
virtual TRI_action_result_t execute (struct TRI_vocbase_s*,
triagens::rest::HttpRequest*,
triagens::basics::Mutex* dataLock,
void** data) = 0;
virtual bool cancel (triagens::basics::Mutex* dataLock,
void** data) = 0;
std::string _type;
std::string _url;

View File

@ -40,6 +40,7 @@
#include "GeneralServer/GeneralServer.h"
using namespace triagens::arango;
using namespace triagens::rest;
// -----------------------------------------------------------------------------
// --SECTION-- public constants
@ -60,12 +61,9 @@ const string RestShardHandler::QUEUE_NAME = "STANDARD";
////////////////////////////////////////////////////////////////////////////////
RestShardHandler::RestShardHandler (triagens::rest::HttpRequest* request,
void* data)
Dispatcher* data)
: RestBaseHandler(request),
_dispatcher(0) {
_dispatcher = static_cast<triagens::rest::Dispatcher*>(data);
_dispatcher(data) {
assert(_dispatcher != 0);
}

View File

@ -45,7 +45,7 @@ namespace triagens {
/// @brief shard control request handler
////////////////////////////////////////////////////////////////////////////////
class RestShardHandler : public triagens::admin::RestBaseHandler {
class RestShardHandler : public admin::RestBaseHandler {
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
@ -57,8 +57,8 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestShardHandler (triagens::rest::HttpRequest* request,
void*);
RestShardHandler (rest::HttpRequest* request,
rest::Dispatcher*);
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
@ -94,7 +94,7 @@ namespace triagens {
/// @brief dispatcher
////////////////////////////////////////////////////////////////////////////////
triagens::rest::Dispatcher* _dispatcher;
rest::Dispatcher* _dispatcher;
////////////////////////////////////////////////////////////////////////////////
/// @brief name of the queue

View File

@ -98,6 +98,14 @@ Job::status_t ServerJob::work () {
return status_t(Job::JOB_FAILED);
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool ServerJob::cancel (bool running) {
return false;
}
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
@ -107,6 +115,7 @@ Job::status_t ServerJob::work () {
////////////////////////////////////////////////////////////////////////////////
bool ServerJob::execute () {
// default to system database
TRI_vocbase_t* vocbase = TRI_UseDatabaseServer(_server, TRI_VOC_SYSTEM_DATABASE);

View File

@ -125,6 +125,12 @@ namespace triagens {
Job::status_t work ();
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool cancel (bool running);
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////

View File

@ -117,7 +117,7 @@ static void DefineApiHandlers (HttpHandlerFactory* factory,
AsyncJobManager* jobManager) {
// add "/version" handler
admin->addBasicHandlers(factory, "/_api", (void*) jobManager);
admin->addBasicHandlers(factory, "/_api", dispatcher->dispatcher(), jobManager);
// add a upgrade warning
factory->addPrefixHandler("/_msg/please-upgrade",
@ -150,8 +150,8 @@ static void DefineApiHandlers (HttpHandlerFactory* factory,
#ifdef TRI_ENABLE_CLUSTER
// add "/shard-comm" handler
factory->addPrefixHandler("/_api/shard-comm",
RestHandlerCreator<RestShardHandler>::createData<void*>,
(void*) dispatcher->dispatcher());
RestHandlerCreator<RestShardHandler>::createData<Dispatcher*>,
dispatcher->dispatcher());
#endif
}
@ -166,7 +166,7 @@ static void DefineAdminHandlers (HttpHandlerFactory* factory,
ApplicationServer* applicationServer) {
// add "/version" handler
admin->addBasicHandlers(factory, "/_admin", (void*) jobManager);
admin->addBasicHandlers(factory, "/_admin", dispatcher->dispatcher(), jobManager);
// add "/_admin/shutdown" handler
factory->addPrefixHandler("/_admin/shutdown",

View File

@ -366,8 +366,6 @@ void ApplicationV8::exitContext (V8Context* context) {
CONDITION_LOCKER(guard, _contextCondition);
context->handleGlobalContextMethods();
// update data for later garbage collection
TRI_v8_global_t* v8g = (TRI_v8_global_t*) context->_isolate->GetData();
context->_hasDeadObjects = v8g->_hasDeadObjects;
@ -376,6 +374,24 @@ void ApplicationV8::exitContext (V8Context* context) {
// exit the context
context->_context->Exit();
context->_isolate->Exit();
// try to execute new global context methods
bool runGlobal = false;
{
MUTEX_LOCKER(context->_globalMethodsLock);
runGlobal = ! context->_globalMethods.empty();
}
if (runGlobal) {
context->_isolate->Enter();
context->_context->Enter();
context->handleGlobalContextMethods();
context->_context->Exit();
context->_isolate->Exit();
}
delete context->_locker;

View File

@ -56,7 +56,8 @@ V8PeriodicJob::V8PeriodicJob (TRI_vocbase_t* vocbase,
_v8Dealer(v8Dealer),
_module(module),
_func(func),
_parameter(parameter) {
_parameter(parameter),
_canceled(0) {
}
// -----------------------------------------------------------------------------
@ -85,6 +86,10 @@ const string& V8PeriodicJob::queue () {
////////////////////////////////////////////////////////////////////////////////
Job::status_t V8PeriodicJob::work () {
if (_canceled) {
return status_t(JOB_DONE);
}
ApplicationV8::V8Context* context
= _v8Dealer->enterContext(_vocbase, 0, true, false);
@ -118,6 +123,18 @@ Job::status_t V8PeriodicJob::work () {
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool V8PeriodicJob::cancel (bool running) {
if (running) {
_canceled = 1;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void V8PeriodicJob::cleanup () {
delete this;
}

View File

@ -84,6 +84,12 @@ namespace triagens {
status_t work ();
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool cancel (bool running);
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -137,6 +143,12 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
const std::string _parameter;
////////////////////////////////////////////////////////////////////////////////
/// @brief cancel flag
////////////////////////////////////////////////////////////////////////////////
volatile sig_atomic_t _canceled;
};
}
}

View File

@ -28,6 +28,7 @@
#include "v8-actions.h"
#include "Actions/actions.h"
#include "Basics/MutexLocker.h"
#include "Basics/ReadLocker.h"
#include "Basics/StringUtils.h"
#include "Basics/WriteLocker.h"
@ -38,8 +39,8 @@
#include "Dispatcher/ApplicationDispatcher.h"
#include "Rest/HttpRequest.h"
#include "Rest/HttpResponse.h"
#include "Scheduler/Scheduler.h"
#include "Scheduler/ApplicationScheduler.h"
#include "Scheduler/Scheduler.h"
#include "V8/v8-conv.h"
#include "V8/v8-utils.h"
#include "V8Server/ApplicationV8.h"
@ -117,7 +118,9 @@ class v8_action_t : public TRI_action_t {
////////////////////////////////////////////////////////////////////////////////
v8_action_t (set<string> const& contexts)
: TRI_action_t(contexts) {
: TRI_action_t(contexts),
_callbacks(),
_callbacksLock() {
_type = "JAVASCRIPT";
}
@ -139,11 +142,13 @@ class v8_action_t : public TRI_action_t {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the callback for a request
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
TRI_action_result_t execute (TRI_vocbase_t* vocbase,
HttpRequest* request) {
HttpRequest* request,
Mutex* dataLock,
void** data) {
TRI_action_result_t result;
// determine whether we should force a re-initialistion of the engine in development mode
@ -187,13 +192,56 @@ class v8_action_t : public TRI_action_t {
}
// and execute it
{
MUTEX_LOCKER(*dataLock);
if (*data != 0) {
result.canceled = true;
GlobalV8Dealer->exitContext(context);
return result;
}
*data = (void*) context->_isolate;
}
result = ExecuteActionVocbase(vocbase, context->_isolate, this, i->second, request);
{
MUTEX_LOCKER(*dataLock);
*data = 0;
}
GlobalV8Dealer->exitContext(context);
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool cancel (Mutex* dataLock, void** data) {
{
MUTEX_LOCKER(*dataLock);
// either we have not yet reached the execute above or we are already done
if (*data == 0) {
*data = (void*) 1; // mark as canceled
}
// data is set, cancel the execution
else {
if (! v8::V8::IsExecutionTerminating((v8::Isolate*) *data)) {
v8::V8::TerminateExecution((v8::Isolate*) *data);
}
}
}
return true;
}
private:
////////////////////////////////////////////////////////////////////////////////
@ -660,20 +708,26 @@ static TRI_action_result_t ExecuteActionVocbase (TRI_vocbase_t* vocbase,
result.isValid = true;
if (tryCatch.HasCaught()) {
v8::Handle<v8::Value> exception = tryCatch.Exception();
bool isSleepAndRequeue = v8g->SleepAndRequeueFuncTempl->HasInstance(exception);
if (tryCatch.CanContinue()) {
v8::Handle<v8::Value> exception = tryCatch.Exception();
bool isSleepAndRequeue = v8g->SleepAndRequeueFuncTempl->HasInstance(exception);
if (isSleepAndRequeue) {
result.requeue = true;
result.sleep = TRI_ObjectToDouble(exception->ToObject()->Get(v8g->SleepKey));
if (isSleepAndRequeue) {
result.requeue = true;
result.sleep = TRI_ObjectToDouble(exception->ToObject()->Get(v8g->SleepKey));
}
else {
string msg = TRI_StringifyV8Exception(&tryCatch);
HttpResponse* response = new HttpResponse(HttpResponse::SERVER_ERROR, request->compatibility());
response->body().appendText(msg);
result.response = response;
}
}
else {
string msg = TRI_StringifyV8Exception(&tryCatch);
HttpResponse* response = new HttpResponse(HttpResponse::SERVER_ERROR, request->compatibility());
response->body().appendText(msg);
result.response = response;
result.isValid = false;
result.canceled = true;
}
}

View File

@ -36,6 +36,7 @@
"ERROR_LOCK_TIMEOUT" : { "code" : 18, "message" : "lock timeout" },
"ERROR_CANNOT_CREATE_DIRECTORY" : { "code" : 19, "message" : "cannot create directory" },
"ERROR_CANNOT_CREATE_TEMP_FILE" : { "code" : 20, "message" : "cannot create temporary file" },
"ERROR_REQUEST_CANCELED" : { "code" : 21, "message" : "canceled request" },
"ERROR_HTTP_BAD_PARAMETER" : { "code" : 400, "message" : "bad parameter" },
"ERROR_HTTP_UNAUTHORIZED" : { "code" : 401, "message" : "unauthorized" },
"ERROR_HTTP_FORBIDDEN" : { "code" : 403, "message" : "forbidden" },

View File

@ -36,6 +36,7 @@
"ERROR_LOCK_TIMEOUT" : { "code" : 18, "message" : "lock timeout" },
"ERROR_CANNOT_CREATE_DIRECTORY" : { "code" : 19, "message" : "cannot create directory" },
"ERROR_CANNOT_CREATE_TEMP_FILE" : { "code" : 20, "message" : "cannot create temporary file" },
"ERROR_REQUEST_CANCELED" : { "code" : 21, "message" : "canceled request" },
"ERROR_HTTP_BAD_PARAMETER" : { "code" : 400, "message" : "bad parameter" },
"ERROR_HTTP_UNAUTHORIZED" : { "code" : 401, "message" : "unauthorized" },
"ERROR_HTTP_FORBIDDEN" : { "code" : 403, "message" : "forbidden" },

View File

@ -123,12 +123,15 @@ void ApplicationAdminServer::allowLogViewer () {
void ApplicationAdminServer::addBasicHandlers (HttpHandlerFactory* factory,
string const& prefix,
void* jobManager) {
Dispatcher* dispatcher,
AsyncJobManager* jobManager) {
factory->addHandler(prefix + "/version", RestHandlerCreator<RestVersionHandler>::createNoData, 0);
pair<Dispatcher*, AsyncJobManager*>* data = new pair<Dispatcher*, AsyncJobManager*>(dispatcher, jobManager);
factory->addPrefixHandler(prefix + "/job",
RestHandlerCreator<RestJobHandler>::createData<void*>,
jobManager);
RestHandlerCreator<RestJobHandler>::createData< pair<Dispatcher*, AsyncJobManager*>* >,
data);
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -38,6 +38,7 @@
namespace triagens {
namespace rest {
class ApplicationServer;
class AsyncJobManager;
class HttpHandlerFactory;
class HttpResponse;
class HttpRequest;
@ -119,7 +120,8 @@ namespace triagens {
void addBasicHandlers (rest::HttpHandlerFactory*,
string const &prefix,
void*);
rest::Dispatcher*,
rest::AsyncJobManager*);
////////////////////////////////////////////////////////////////////////////////
/// @brief adds the http handlers for administration

View File

@ -113,6 +113,31 @@ void RestBaseHandler::generateResult (HttpResponse::HttpResponseCode code,
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates a cancel message
////////////////////////////////////////////////////////////////////////////////
void RestBaseHandler::generateCanceled () {
TRI_json_t* json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);
char* msg = TRI_DuplicateString("request canceled");
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json,
"error", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json,
"code", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (int32_t) HttpResponse::REQUEST_TIMEOUT));
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json,
"errorNum", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (int32_t) TRI_ERROR_REQUEST_CANCELED));
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json,
"errorMessage", TRI_CreateStringJson(TRI_CORE_MEM_ZONE, msg));
generateResult(HttpResponse::REQUEST_TIMEOUT, json);
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generates an error
////////////////////////////////////////////////////////////////////////////////

View File

@ -121,6 +121,12 @@ namespace triagens {
virtual void generateResult (rest::HttpResponse::HttpResponseCode,
TRI_json_t const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief generates a cancel message
////////////////////////////////////////////////////////////////////////////////
virtual void generateCanceled ();
////////////////////////////////////////////////////////////////////////////////
/// @brief generates an error
////////////////////////////////////////////////////////////////////////////////

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2010-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_ADMIN_REST_HANDLER_CREATOR_H
@ -42,11 +42,6 @@ namespace triagens {
// --SECTION-- class RestAdminBaseHandler
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief creator function
////////////////////////////////////////////////////////////////////////////////
@ -54,19 +49,10 @@ namespace triagens {
template<typename H>
class RestHandlerCreator : public H {
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public static methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -97,10 +83,6 @@ namespace triagens {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#endif
// Local Variables:

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2010-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "RestJobHandler.h"
@ -30,6 +30,7 @@
#include "Basics/StringUtils.h"
#include "BasicsC/conversions.h"
#include "BasicsC/tri-strings.h"
#include "Dispatcher/Dispatcher.h"
#include "HttpServer/AsyncJobManager.h"
#include "Rest/HttpRequest.h"
#include "Rest/HttpResponse.h"
@ -46,45 +47,28 @@ using namespace std;
////////////////////////////////////////////////////////////////////////////////
/// @brief name of the queue
////////////////////////////////////////////////////////////////////////////////
const string RestJobHandler::QUEUE_NAME = "STANDARD";
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
const string RestJobHandler::QUEUE_NAME = "STANDARD";
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestJobHandler::RestJobHandler (HttpRequest* request, void* data)
: RestBaseHandler(request) {
_jobManager = static_cast<AsyncJobManager*>(data);
RestJobHandler::RestJobHandler (HttpRequest* request,
pair<Dispatcher*, AsyncJobManager*>* data)
: RestBaseHandler(request),
_dispatcher(data->first),
_jobManager(data->second) {
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -106,6 +90,7 @@ string const& RestJobHandler::queue () const {
////////////////////////////////////////////////////////////////////////////////
HttpHandler::status_t RestJobHandler::execute () {
// extract the sub-request type
HttpRequest::HttpRequestType type = _request->requestType();
@ -113,7 +98,17 @@ HttpHandler::status_t RestJobHandler::execute () {
getJob();
}
else if (type == HttpRequest::HTTP_REQUEST_PUT) {
putJob();
const vector<string>& suffix = _request->suffix();
if (suffix.size() == 1) {
putJob();
}
else if (suffix.size() == 2) {
putJobMethod();
}
else {
generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
}
}
else if (type == HttpRequest::HTTP_REQUEST_DELETE) {
deleteJob();
@ -125,19 +120,10 @@ HttpHandler::status_t RestJobHandler::execute () {
return status_t(HANDLER_DONE);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief fetches a job result and removes it from the queue
///
@ -147,7 +133,7 @@ HttpHandler::status_t RestJobHandler::execute () {
///
/// @RESTURLPARAM{job-id,string,required}
/// The async job id.
///
///
/// @RESTDESCRIPTION
/// Returns the result of an async job identified by `job-id`.
/// If the async job result is present on the server, the result will be removed
@ -155,7 +141,7 @@ HttpHandler::status_t RestJobHandler::execute () {
/// `job-id` once.
///
/// The method will return the original job result's headers and body, plus
/// the additional HTTP header `x-arango-async-job-id`. If this header is
/// the additional HTTP header `x-arango-async-job-id`. If this header is
/// present, then the job was found and the response contains the original job's
/// result. If the header is not present, the job was not found and the response
/// contains status information from the job amanger.
@ -170,15 +156,15 @@ HttpHandler::status_t RestJobHandler::execute () {
/// @RESTRETURNCODE{204}
/// is returned if the job requested via `job-id` is still in the queue of
/// pending (or not yet finished) jobs. In this case, no `x-arango-async-id`
/// HTTP header will be returned.
/// HTTP header will be returned.
///
/// @RESTRETURNCODE{400}
/// is returned if no `job-id` was specified in the request. In this case, no
/// `x-arango-async-id` HTTP header will be returned.
///
/// @RESTRETURNCODE{404}
/// is returned if the job was not found or already deleted or fetched from the
/// job result list. In this case, no `x-arango-async-id` HTTP header will be
/// is returned if the job was not found or already deleted or fetched from the
/// job result list. In this case, no `x-arango-async-id` HTTP header will be
/// returned.
///
/// @EXAMPLES
@ -187,9 +173,9 @@ HttpHandler::status_t RestJobHandler::execute () {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerPutNone}
/// var url = "/_api/job/";
///
///
/// var response = logCurlRequest('PUT', url, "");
///
///
/// assert(response.code === 400);
/// logRawResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
@ -198,9 +184,9 @@ HttpHandler::status_t RestJobHandler::execute () {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerPutInvalid}
/// var url = "/_api/job/foobar";
///
///
/// var response = logCurlRequest('PUT', url, "");
///
///
/// assert(response.code === 404);
/// logRawResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
@ -209,9 +195,9 @@ HttpHandler::status_t RestJobHandler::execute () {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerPutGet}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -228,9 +214,9 @@ HttpHandler::status_t RestJobHandler::execute () {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerPutFail}
/// var url = "/_api/collection";
///
///
/// var response = logCurlRequest('POST', url, '{"name":" this name is invalid "}', { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -242,16 +228,10 @@ HttpHandler::status_t RestJobHandler::execute () {
/// assert(response.headers['x-arango-async-id'] === id);
/// logRawResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void RestJobHandler::putJob () {
const vector<string> suffix = _request->suffix();
if (suffix.size() != 1) {
generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
return;
}
const vector<string>& suffix = _request->suffix();
const string& value = suffix[0];
uint64_t jobId = StringUtils::uint64(value);
@ -263,7 +243,7 @@ void RestJobHandler::putJob () {
generateError(HttpResponse::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
return;
}
if (status == AsyncJobResult::JOB_PENDING) {
// job is still pending
_response = createResponse(HttpResponse::NO_CONTENT);
@ -279,18 +259,80 @@ void RestJobHandler::putJob () {
}
// return the original response
_response = response;
_response = response;
// plus a new header
_response->setHeader("x-arango-async-id", value);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief cancels an async job
///
/// @RESTHEADER{PUT /_api/job/cancel/`job-id`,Cancels an async job}
///
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{job-id,string,required}
/// The async job id.
///
/// @RESTDESCRIPTION
/// Cancels the currently runing job identified by `job-id`. Note that it still
/// might take some time to actually cancel the running async job.
///
/// @RESTRETURNCODES
///
/// Any HTTP status code might be returned by this method. To tell the original
/// job response from a job manager response apart, check for the HTTP header
/// `x-arango-async-id`. If it is present, the response contains the original
/// job's result. Otherwise the response is from the job manager.
///
/// @RESTRETURNCODE{200}
/// cancel has been initiated.
///
/// @RESTRETURNCODE{400}
/// is returned if no `job-id` was specified in the request. In this case, no
/// `x-arango-async-id` HTTP header will be returned.
///
/// @RESTRETURNCODE{404}
/// is returned if the job was not found or already deleted or fetched from the
/// job result list. In this case, no `x-arango-async-id` HTTP header will be
/// returned.
////////////////////////////////////////////////////////////////////////////////
void RestJobHandler::putJobMethod () {
const vector<string>& suffix = _request->suffix();
const string& method = suffix[0];
const string& value = suffix[1];
uint64_t jobId = StringUtils::uint64(value);
if (method == "cancel") {
bool status = _dispatcher->cancelJob(jobId);
// unknown or already fetched job
if (! status) {
generateError(HttpResponse::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
}
else {
TRI_json_t* json = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "result", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
generateResult(json);
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
}
return;
}
else {
generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief trampoline function for HTTP GET requests
////////////////////////////////////////////////////////////////////////////////
void RestJobHandler::getJob () {
const vector<string> suffix = _request->suffix();
if (suffix.size() != 1) {
generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
return;
@ -328,14 +370,14 @@ void RestJobHandler::getJob () {
///
/// @RESTRETURNCODE{204}
/// is returned if the job requested via `job-id` is still in the queue of
/// pending (or not yet finished) jobs.
/// pending (or not yet finished) jobs.
///
/// @RESTRETURNCODE{400}
/// is returned if no `job-id` was specified in the request.
/// is returned if no `job-id` was specified in the request.
///
/// @RESTRETURNCODE{404}
/// is returned if the job was not found or already deleted or fetched from the
/// job result list.
/// is returned if the job was not found or already deleted or fetched from the
/// job result list.
///
/// @EXAMPLES
///
@ -343,9 +385,9 @@ void RestJobHandler::getJob () {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerGetIdDone}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// var id = response.headers['x-arango-async-id'];
/// logRawResponse(response);
@ -364,9 +406,9 @@ void RestJobHandler::getJob () {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerGetIdPending}
/// var url = "/_admin/sleep?duration=3";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// var id = response.headers['x-arango-async-id'];
/// logRawResponse(response);
@ -377,7 +419,7 @@ void RestJobHandler::getJob () {
///
/// response = curlRequest('DELETE', "/_api/job/" + id);
/// @END_EXAMPLE_ARANGOSH_RUN
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void RestJobHandler::getJobId (std::string const& value) {
uint64_t jobId = StringUtils::uint64(value);
@ -391,13 +433,13 @@ void RestJobHandler::getJobId (std::string const& value) {
generateError(HttpResponse::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
return;
}
if (status == AsyncJobResult::JOB_PENDING) {
// job is still pending
_response = createResponse(HttpResponse::NO_CONTENT);
return;
}
_response = createResponse(HttpResponse::OK);
}
@ -409,7 +451,7 @@ void RestJobHandler::getJobId (std::string const& value) {
/// @RESTURLPARAMETERS
///
/// @RESTURLPARAM{type,string,required}
/// The type of jobs to return. The type can be either `done` or `pending`.
/// The type of jobs to return. The type can be either `done` or `pending`.
/// Setting the type to `done` will make the method return the ids of already
/// completed async jobs for which results can be fetched.
/// Setting the type to `pending` will return the ids of not yet finished
@ -420,7 +462,7 @@ void RestJobHandler::getJobId (std::string const& value) {
/// @RESTQUERYPARAM{count,number,optional}
/// The maximum number of ids to return per call. If not specified, a server-defined
/// maximum value will be used.
///
///
/// @RESTDESCRIPTION
/// Returns the list of ids of async jobs with a specific status (either done
/// or pending). The list can be used by the client to get an overview of the
@ -441,9 +483,9 @@ void RestJobHandler::getJobId (std::string const& value) {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerGetDone}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -461,9 +503,9 @@ void RestJobHandler::getJobId (std::string const& value) {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerGetPending}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -477,7 +519,7 @@ void RestJobHandler::getJobId (std::string const& value) {
/// response = curlRequest('DELETE', "/_api/job/all");
/// assert(response.code === 200);
/// @END_EXAMPLE_ARANGOSH_RUN
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void RestJobHandler::getJobType (std::string const& type) {
size_t count = 100;
@ -510,7 +552,7 @@ void RestJobHandler::getJobType (std::string const& type) {
TRI_PushBack3ListJson(TRI_CORE_MEM_ZONE, json, TRI_CreateStringJson(TRI_CORE_MEM_ZONE, idString));
}
generateResult(json);
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
}
@ -528,7 +570,7 @@ void RestJobHandler::getJobType (std::string const& type) {
///
/// @RESTURLPARAM{type,string,required}
/// The type of jobs to delete. `type` can be:
/// - `all`: deletes all jobs results. Currently executing or queued async jobs
/// - `all`: deletes all jobs results. Currently executing or queued async jobs
/// will not be stopped by this call.
/// - `expired`: deletes expired results. To determine the expiration status of
/// a result, pass the `stamp` URL parameter. `stamp` needs to be a UNIX
@ -542,10 +584,10 @@ void RestJobHandler::getJobType (std::string const& type) {
///
/// @RESTQUERYPARAM{stamp,number,optional}
/// A UNIX timestamp specifying the expiration threshold when type is `expired`.
///
///
/// @RESTDESCRIPTION
/// Deletes either all job results, expired job results, or the result of a
/// specific job. Clients can use this method to perform an eventual garbage
/// Deletes either all job results, expired job results, or the result of a
/// specific job. Clients can use this method to perform an eventual garbage
/// collection of job results.
///
/// @RESTRETURNCODES
@ -567,9 +609,9 @@ void RestJobHandler::getJobType (std::string const& type) {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerDeleteAll}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -584,9 +626,9 @@ void RestJobHandler::getJobType (std::string const& type) {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerDeleteExpired}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -602,9 +644,9 @@ void RestJobHandler::getJobType (std::string const& type) {
///
/// @EXAMPLE_ARANGOSH_RUN{RestJobHandlerDeleteId}
/// var url = "/_api/version";
///
///
/// var response = logCurlRequest('GET', url, "", { "x-arango-async": "store" });
///
///
/// assert(response.code === 202);
/// logRawResponse(response);
///
@ -623,7 +665,7 @@ void RestJobHandler::getJobType (std::string const& type) {
/// assert(response.code === 404);
/// logJsonResponse(response);
/// @END_EXAMPLE_ARANGOSH_RUN
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void RestJobHandler::deleteJob () {
const vector<string> suffix = _request->suffix();
@ -632,7 +674,7 @@ void RestJobHandler::deleteJob () {
generateError(HttpResponse::BAD, TRI_ERROR_HTTP_BAD_PARAMETER);
return;
}
const string& value = suffix[0];
if (value == "all") {
@ -654,7 +696,7 @@ void RestJobHandler::deleteJob () {
uint64_t jobId = StringUtils::uint64(value);
bool found = _jobManager->deleteJobResult(jobId);
if (! found) {
generateError(HttpResponse::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
return;
@ -665,7 +707,7 @@ void RestJobHandler::deleteJob () {
if (json != 0) {
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "result", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, true));
generateResult(json);
TRI_FreeJson(TRI_CORE_MEM_ZONE, json);
}
@ -674,10 +716,6 @@ void RestJobHandler::deleteJob () {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}"

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2010-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2010-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_ADMIN_REST_JOB_HANDLER_H
@ -34,6 +34,7 @@
namespace triagens {
namespace rest {
class AsyncJobManager;
class Dispatcher;
}
namespace admin {
@ -42,51 +43,29 @@ namespace triagens {
// --SECTION-- class RestJobHandler
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief job control request handler
////////////////////////////////////////////////////////////////////////////////
class RestJobHandler : public RestBaseHandler {
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
RestJobHandler (rest::HttpRequest* request, void*);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
RestJobHandler (rest::HttpRequest* request,
pair<rest::Dispatcher*, rest::AsyncJobManager*>*);
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -107,25 +86,22 @@ namespace triagens {
status_t execute ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief put handler
////////////////////////////////////////////////////////////////////////////////
void putJob ();
////////////////////////////////////////////////////////////////////////////////
/// @brief put method handler
////////////////////////////////////////////////////////////////////////////////
void putJobMethod ();
////////////////////////////////////////////////////////////////////////////////
/// @brief get handler
////////////////////////////////////////////////////////////////////////////////
@ -150,26 +126,23 @@ namespace triagens {
void deleteJob ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup RestServer
/// @{
/// @brief dispatcher
////////////////////////////////////////////////////////////////////////////////
private:
rest::Dispatcher* _dispatcher;
////////////////////////////////////////////////////////////////////////////////
/// @brief async job manager
////////////////////////////////////////////////////////////////////////////////
AsyncJobManager* _jobManager;
rest::AsyncJobManager* _jobManager;
////////////////////////////////////////////////////////////////////////////////
/// @brief name of the queue
@ -177,18 +150,10 @@ namespace triagens {
static const std::string QUEUE_NAME;
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
};
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#endif
// Local Variables:

View File

@ -23,6 +23,7 @@ ERROR_TYPE_ERROR,17,"type error","Will be raised when a type error is unencounte
ERROR_LOCK_TIMEOUT,18,"lock timeout","Will be raised when there's a timeout waiting for a lock."
ERROR_CANNOT_CREATE_DIRECTORY,19,"cannot create directory","Will be raised when an attempt to create a directory fails."
ERROR_CANNOT_CREATE_TEMP_FILE,20,"cannot create temporary file","Will be raised when an attempt to create a temporary file fails."
ERROR_REQUEST_CANCELED,21,"canceled request","Will be raised when a request is canceled by the user."
################################################################################
## HTTP standard errors

View File

@ -32,6 +32,7 @@ void TRI_InitialiseErrorMessages (void) {
REG_ERROR(ERROR_LOCK_TIMEOUT, "lock timeout");
REG_ERROR(ERROR_CANNOT_CREATE_DIRECTORY, "cannot create directory");
REG_ERROR(ERROR_CANNOT_CREATE_TEMP_FILE, "cannot create temporary file");
REG_ERROR(ERROR_REQUEST_CANCELED, "canceled request");
REG_ERROR(ERROR_HTTP_BAD_PARAMETER, "bad parameter");
REG_ERROR(ERROR_HTTP_UNAUTHORIZED, "unauthorized");
REG_ERROR(ERROR_HTTP_FORBIDDEN, "forbidden");

View File

@ -53,6 +53,8 @@ extern "C" {
/// Will be raised when an attempt to create a directory fails.
/// - 20: @LIT{cannot create temporary file}
/// Will be raised when an attempt to create a temporary file fails.
/// - 21: @LIT{canceled request}
/// Will be raised when a request is canceled by the user.
/// - 400: @LIT{bad parameter}
/// Will be raised when the HTTP request does not fulfill the requirements.
/// - 401: @LIT{unauthorized}
@ -717,6 +719,16 @@ void TRI_InitialiseErrorMessages (void);
#define TRI_ERROR_CANNOT_CREATE_TEMP_FILE (20)
////////////////////////////////////////////////////////////////////////////////
/// @brief 21: ERROR_REQUEST_CANCELED
///
/// canceled request
///
/// Will be raised when a request is canceled by the user.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_REQUEST_CANCELED (21)
////////////////////////////////////////////////////////////////////////////////
/// @brief 400: ERROR_HTTP_BAD_PARAMETER
///

View File

@ -157,14 +157,29 @@ bool Dispatcher::addJob (Job* job) {
// add the job to the list of ready jobs
if (! queue->addJob(job)) {
// queue full etc.
return false;
return false; // queue full etc.
}
// indicate success, BUT never access job after it has been added to the queue
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to cancel a job
////////////////////////////////////////////////////////////////////////////////
bool Dispatcher::cancelJob (uint64_t jobId) {
bool done = false;
for (map<string, DispatcherQueue*>::iterator i = _queues.begin(); i != _queues.end() && ! done; ++i) {
DispatcherQueue* q = i->second;
done = q->cancelJob(jobId);
}
return done;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief start the dispatcher
////////////////////////////////////////////////////////////////////////////////
@ -281,7 +296,6 @@ void Dispatcher::reportStatus () {
// --SECTION-- protected methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief looks up a queue
////////////////////////////////////////////////////////////////////////////////

View File

@ -139,6 +139,12 @@ namespace triagens {
bool addJob (Job*);
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to cancel a job
////////////////////////////////////////////////////////////////////////////////
bool cancelJob (uint64_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief starts the dispatcher
////////////////////////////////////////////////////////////////////////////////

View File

@ -55,6 +55,7 @@ DispatcherQueue::DispatcherQueue (Scheduler* scheduler,
: _name(name),
_accessQueue(),
_readyJobs(),
_runningJobs(),
_maxSize(maxSize),
_stopping(0),
_monopolizer(0),
@ -95,8 +96,8 @@ bool DispatcherQueue::addJob (Job* job) {
CONDITION_LOCKER(guard, _accessQueue);
// queue is full
if (_readyJobs.size() >= _maxSize) {
// queue is full
return false;
}
@ -111,6 +112,60 @@ bool DispatcherQueue::addJob (Job* job) {
return true;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to cancel a job
////////////////////////////////////////////////////////////////////////////////
bool DispatcherQueue::cancelJob (uint64_t jobId) {
CONDITION_LOCKER(guard, _accessQueue);
if (jobId == 0) {
return false;
}
// job is already running, try to cancel it
for (set<Job*>::iterator it = _runningJobs.begin(); it != _runningJobs.end(); ++it) {
Job* job = *it;
if (job->id() == jobId) {
job->cancel(true);
return true;
}
}
// maybe there is a waiting job with this it, try to remove it
for (list<Job*>::iterator it = _readyJobs.begin(); it != _readyJobs.end(); ++it) {
Job* job = *it;
if (job->id() == jobId) {
bool canceled = job->cancel(false);
if (canceled) {
try {
job->setDispatcherThread(0);
job->cleanup();
}
catch (...) {
#ifdef TRI_HAVE_POSIX_THREADS
if (_stopping != 0) {
LOG_WARNING("caught cancellation exception during cleanup");
throw;
}
#endif
LOG_WARNING("caught error while cleaning up!");
}
_readyJobs.erase(it);
}
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief downgrades the thread to special
////////////////////////////////////////////////////////////////////////////////

View File

@ -94,6 +94,12 @@ namespace triagens {
bool addJob (Job*);
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to cancel a job
////////////////////////////////////////////////////////////////////////////////
bool cancelJob (uint64_t);
////////////////////////////////////////////////////////////////////////////////
/// @brief downgrades the thread to special
////////////////////////////////////////////////////////////////////////////////
@ -160,6 +166,12 @@ namespace triagens {
list<Job*> _readyJobs;
/////////////////////////////////////////////////////////////////////////////
/// @brief current running job
/////////////////////////////////////////////////////////////////////////////
set<Job*> _runningJobs;
/////////////////////////////////////////////////////////////////////////////
/// @brief maximum queue size (number of jobs)
/////////////////////////////////////////////////////////////////////////////

View File

@ -111,6 +111,9 @@ void DispatcherThread::run () {
_queue->_monopolizer = this;
}
// set running job
_queue->_runningJobs.insert(job);
// now release the queue lock (initialise is inside the lock, work outside)
_queue->_accessQueue.unlock();
@ -186,6 +189,11 @@ void DispatcherThread::run () {
status = Job::status_t(Job::JOB_FAILED);
}
// clear running job
_queue->_accessQueue.lock();
_queue->_runningJobs.erase(job);
_queue->_accessQueue.unlock();
// trigger GC
/* TODO: tick is a no-op. decide whether it should be deleted
tick(false);

View File

@ -40,7 +40,8 @@ using namespace std;
////////////////////////////////////////////////////////////////////////////////
Job::Job (string const& name)
: _name(name) {
: _name(name),
_id(0) {
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -128,11 +128,27 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief getter for the name
/// @brief gets the name
////////////////////////////////////////////////////////////////////////////////
const string& getName () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief assign an id to the job. note: the id might be 0
////////////////////////////////////////////////////////////////////////////////
void assignId (uint64_t id) {
_id = id;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief assign an id to the job
////////////////////////////////////////////////////////////////////////////////
uint64_t id () const {
return _id;
}
// -----------------------------------------------------------------------------
// --SECTION-- virtual public methods
// -----------------------------------------------------------------------------
@ -165,6 +181,12 @@ namespace triagens {
virtual status_t work () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to cancel execution
////////////////////////////////////////////////////////////////////////////////
virtual bool cancel (bool running) = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief cleans up after work and delete
////////////////////////////////////////////////////////////////////////////////
@ -194,6 +216,12 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
const string& _name;
////////////////////////////////////////////////////////////////////////////////
/// @brief job id (only used for detached jobs)
////////////////////////////////////////////////////////////////////////////////
uint64_t _id;
};
}
}

View File

@ -478,14 +478,13 @@ namespace triagens {
/// @brief the dispatcher
////////////////////////////////////////////////////////////////////////////////
Dispatcher* _dispatcher;
Dispatcher* _dispatcher;
////////////////////////////////////////////////////////////////////////////////
/// @brief the job manager
////////////////////////////////////////////////////////////////////////////////
AsyncJobManager* _jobManager;
AsyncJobManager* _jobManager;
};
}
}

View File

@ -72,7 +72,6 @@ namespace triagens {
: Job("HttpServerJob"),
_server(server),
_handler(handler),
_id(0),
_shutdown(0),
_abandon(false),
_isDetached(isDetached) {
@ -91,22 +90,6 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief assign an id to the job. note: the id might be 0
////////////////////////////////////////////////////////////////////////////////
void assignId (uint64_t id) {
_id = id;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief assign an id to the job
////////////////////////////////////////////////////////////////////////////////
uint64_t id () const {
return _id;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief abandon job
////////////////////////////////////////////////////////////////////////////////
@ -184,6 +167,14 @@ namespace triagens {
return status.jobStatus();
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
bool cancel (bool running) {
return _handler->cancel(running);
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -240,12 +231,6 @@ namespace triagens {
H* _handler;
////////////////////////////////////////////////////////////////////////////////
/// @brief job id (only used for detached jobs)
////////////////////////////////////////////////////////////////////////////////
uint64_t _id;
////////////////////////////////////////////////////////////////////////////////
/// @brief shutdown in progress
////////////////////////////////////////////////////////////////////////////////

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,11 +22,11 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2004-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2004-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_HTTP_SERVER_JOB_MANAGER_H
#define TRIAGENS_HTTP_SERVER_JOB_MANAGER_H 1
#ifndef TRIAGENS_HTTP_SERVER_ASYNC_JOB_MANAGER_H
#define TRIAGENS_HTTP_SERVER_ASYNC_JOB_MANAGER_H 1
#include "Basics/Common.h"
#include "Basics/ReadLocker.h"
@ -43,6 +43,10 @@ namespace triagens {
// --SECTION-- class AsyncCallbackContext
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief AsyncCallbackContext
////////////////////////////////////////////////////////////////////////////////
class AsyncCallbackContext {
// -----------------------------------------------------------------------------
@ -50,11 +54,20 @@ namespace triagens {
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
AsyncCallbackContext (std::string const& coordHeader)
: _coordHeader(coordHeader),
_response(0) {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief destructor
////////////////////////////////////////////////////////////////////////////////
~AsyncCallbackContext () {
if (_response != 0) {
delete _response;
@ -67,7 +80,11 @@ namespace triagens {
public:
string& getCoordinatorHeader() {
////////////////////////////////////////////////////////////////////////////////
/// @brief gets the coordinator header
////////////////////////////////////////////////////////////////////////////////
string& getCoordinatorHeader () {
return _coordHeader;
}
@ -77,8 +94,16 @@ namespace triagens {
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief coordinator header
////////////////////////////////////////////////////////////////////////////////
std::string _coordHeader;
////////////////////////////////////////////////////////////////////////////////
/// @brief http response
////////////////////////////////////////////////////////////////////////////////
HttpResponse* _response;
};
@ -86,6 +111,10 @@ namespace triagens {
// --SECTION-- class AsyncJobResult
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief AsyncJobResult
////////////////////////////////////////////////////////////////////////////////
struct AsyncJobResult {
// -----------------------------------------------------------------------------
@ -95,7 +124,7 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief job statuses
/// @brief job states
////////////////////////////////////////////////////////////////////////////////
typedef enum {
@ -108,7 +137,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
/// @brief id typedef
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t IdType;
// -----------------------------------------------------------------------------
@ -119,7 +148,7 @@ namespace triagens {
/// @brief constructor for an unspecified job result
////////////////////////////////////////////////////////////////////////////////
AsyncJobResult () :
AsyncJobResult () :
_jobId(0),
_response(0),
_stamp(0.0),
@ -130,8 +159,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor for a specific job result
////////////////////////////////////////////////////////////////////////////////
AsyncJobResult (IdType jobId,
AsyncJobResult (IdType jobId,
HttpResponse* response,
double stamp,
Status status,
@ -158,7 +187,7 @@ namespace triagens {
/// @brief job id
////////////////////////////////////////////////////////////////////////////////
IdType _jobId;
IdType _jobId;
////////////////////////////////////////////////////////////////////////////////
/// @brief the full HTTP response object of the job, can be 0
@ -170,20 +199,19 @@ namespace triagens {
/// @brief job creation stamp
////////////////////////////////////////////////////////////////////////////////
double _stamp;
double _stamp;
////////////////////////////////////////////////////////////////////////////////
/// @brief job status
////////////////////////////////////////////////////////////////////////////////
Status _status;
Status _status;
////////////////////////////////////////////////////////////////////////////////
/// @brief callback context object (normally 0, used in cluster operations)
////////////////////////////////////////////////////////////////////////////////
AsyncCallbackContext* _ctx;
};
// -----------------------------------------------------------------------------
@ -197,7 +225,31 @@ namespace triagens {
AsyncJobManager& operator= (AsyncJobManager const&);
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// --SECTION-- public types
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief callback typedef
////////////////////////////////////////////////////////////////////////////////
typedef void (*callback_fptr)(string&, HttpResponse*);
////////////////////////////////////////////////////////////////////////////////
/// @brief generate typedef
////////////////////////////////////////////////////////////////////////////////
typedef uint64_t (*generate_fptr)();
////////////////////////////////////////////////////////////////////////////////
/// @brief joblist typedef
////////////////////////////////////////////////////////////////////////////////
typedef std::map<AsyncJobResult::IdType, AsyncJobResult> JobList;
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
public:
@ -206,12 +258,12 @@ namespace triagens {
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
AsyncJobManager (uint64_t (*idFunc)(),
void (*callbackFunc)(string&, HttpResponse*))
AsyncJobManager (generate_fptr idFunc,
callback_fptr callback)
: _lock(),
_jobs(),
generate(idFunc),
callback(callbackFunc) {
callback(callback) {
}
////////////////////////////////////////////////////////////////////////////////
@ -221,33 +273,23 @@ namespace triagens {
~AsyncJobManager () {
}
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief joblist typedef
////////////////////////////////////////////////////////////////////////////////
typedef std::map<AsyncJobResult::IdType, AsyncJobResult> JobList;
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief get the result of an async job, and optionally remove it from the
/// list of done jobs if it is completed
/// @brief gets the result of an async job
///
/// Get the result of an async job, and optionally remove it from the list of
/// done jobs if it is completed.
////////////////////////////////////////////////////////////////////////////////
HttpResponse* getJobResult (AsyncJobResult::IdType jobId,
AsyncJobResult::Status& status,
bool removeFromList) {
bool removeFromList) {
WRITE_LOCKER(_lock);
JobList::iterator it = _jobs.find(jobId);
JobList::iterator it = _jobs.find(jobId);
if (it == _jobs.end()) {
status = AsyncJobResult::JOB_UNDEFINED;
@ -258,7 +300,7 @@ namespace triagens {
status = (*it).second._status;
if (status == AsyncJobResult::JOB_PENDING) {
return 0;
return 0;
}
if (! removeFromList) {
@ -271,13 +313,13 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief delete the result of an async job, without returning it
/// @brief deletes the result of an async job, without returning it
////////////////////////////////////////////////////////////////////////////////
bool deleteJobResult (AsyncJobResult::IdType jobId) {
WRITE_LOCKER(_lock);
JobList::iterator it = _jobs.find(jobId);
JobList::iterator it = _jobs.find(jobId);
if (it == _jobs.end()) {
return false;
@ -295,7 +337,7 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief delete all results
/// @brief deletes all results
////////////////////////////////////////////////////////////////////////////////
void deleteJobResults () {
@ -317,7 +359,7 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief delete expired results
/// @brief deletes expired results
////////////////////////////////////////////////////////////////////////////////
void deleteExpiredJobResults (double stamp) {
@ -344,26 +386,26 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the list of pending jobs
/// @brief returns the list of pending jobs
////////////////////////////////////////////////////////////////////////////////
const std::vector<AsyncJobResult::IdType> pending (size_t maxCount) {
const std::vector<AsyncJobResult::IdType> pending (size_t maxCount) {
return byStatus(AsyncJobResult::JOB_PENDING, maxCount);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the list of done jobs
/// @brief returns the list of done jobs
////////////////////////////////////////////////////////////////////////////////
const std::vector<AsyncJobResult::IdType> done (size_t maxCount) {
const std::vector<AsyncJobResult::IdType> done (size_t maxCount) {
return byStatus(AsyncJobResult::JOB_DONE, maxCount);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the list of jobs by status
/// @brief returns the list of jobs by status
////////////////////////////////////////////////////////////////////////////////
const std::vector<AsyncJobResult::IdType> byStatus (AsyncJobResult::Status status,
const std::vector<AsyncJobResult::IdType> byStatus (AsyncJobResult::Status status,
size_t maxCount) {
vector<AsyncJobResult::IdType> jobs;
size_t n = 0;
@ -392,12 +434,12 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief initialise an async job
/// @brief initialises an async job
////////////////////////////////////////////////////////////////////////////////
template<typename S, typename HF>
void initAsyncJob (GeneralServerJob<S, typename HF::GeneralHandler>* job,
uint64_t* jobId) {
void initAsyncJob (GeneralServerJob<S, typename HF::GeneralHandler>* job,
uint64_t* jobId) {
if (jobId == 0) {
return;
}
@ -417,8 +459,11 @@ namespace triagens {
ctx = new AsyncCallbackContext(std::string(hdr));
}
AsyncJobResult ajr(*jobId, 0, TRI_microtime(),
AsyncJobResult::JOB_PENDING, ctx);
AsyncJobResult ajr(*jobId,
0,
TRI_microtime(),
AsyncJobResult::JOB_PENDING,
ctx);
WRITE_LOCKER(_lock);
@ -426,13 +471,13 @@ namespace triagens {
}
////////////////////////////////////////////////////////////////////////////////
/// @brief finish the execution of an async job
/// @brief finishes the execution of an async job
////////////////////////////////////////////////////////////////////////////////
template<typename S, typename HF>
void finishAsyncJob (GeneralServerJob<S, typename HF::GeneralHandler>* job) {
void finishAsyncJob (GeneralServerJob<S, typename HF::GeneralHandler>* job) {
assert(job != 0);
typename HF::GeneralHandler* handler = job->getHandler();
assert(handler != 0);
@ -441,18 +486,18 @@ namespace triagens {
if (jobId == 0) {
return;
}
const double now = TRI_microtime();
AsyncCallbackContext* ctx = 0;
HttpResponse* response = 0;
{
WRITE_LOCKER(_lock);
JobList::iterator it = _jobs.find(jobId);
JobList::iterator it = _jobs.find(jobId);
if (it == _jobs.end()) {
// job is already deleted.
// do nothing here. the dispatcher will throw away the handler,
// do nothing here. the dispatcher will throw away the handler,
// which will also dispose the response
return;
}
@ -461,7 +506,7 @@ namespace triagens {
(*it).second._response = response;
(*it).second._status = AsyncJobResult::JOB_DONE;
(*it).second._stamp = now;
(*it).second._stamp = now;
ctx = (*it).second._ctx;
@ -497,29 +542,27 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
/// @brief lock to protect the _jobs map
////////////////////////////////////////////////////////////////////////////////
basics::ReadWriteLock _lock;
basics::ReadWriteLock _lock;
////////////////////////////////////////////////////////////////////////////////
/// @brief list of pending/done async jobs
////////////////////////////////////////////////////////////////////////////////
JobList _jobs;
JobList _jobs;
////////////////////////////////////////////////////////////////////////////////
/// @brief function pointer for id generation
////////////////////////////////////////////////////////////////////////////////
uint64_t (*generate)();
generate_fptr generate;
////////////////////////////////////////////////////////////////////////////////
/// @brief function pointer for callback registered at initialisation
////////////////////////////////////////////////////////////////////////////////
void (*callback)(string& coordinator, HttpResponse* response);
callback_fptr callback;
};
}
}

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2009-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "HttpHandler.h"
@ -40,11 +40,6 @@ using namespace triagens::rest;
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new handler
////////////////////////////////////////////////////////////////////////////////
@ -69,19 +64,10 @@ HttpHandler::~HttpHandler () {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the response
////////////////////////////////////////////////////////////////////////////////
@ -110,19 +96,10 @@ HttpRequest* HttpHandler::stealRequest () {
return tmp;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
@ -130,6 +107,7 @@ HttpRequest* HttpHandler::stealRequest () {
Job* HttpHandler::createJob (AsyncJobServer* server,
bool isDetached) {
HttpServer* httpServer = dynamic_cast<HttpServer*>(server);
// check if we are an HTTP server at all
if (httpServer != 0) {
return new GeneralServerJob<HttpServer, HttpHandlerFactory::GeneralHandler>(httpServer, this, isDetached);
@ -137,6 +115,7 @@ Job* HttpHandler::createJob (AsyncJobServer* server,
// check if we are an HTTPs server at all
HttpsServer* httpsServer = dynamic_cast<HttpsServer*>(server);
if (httpsServer != 0) {
return new GeneralServerJob<HttpsServer, HttpHandlerFactory::GeneralHandler>(httpsServer, this, isDetached);
}
@ -145,19 +124,10 @@ Job* HttpHandler::createJob (AsyncJobServer* server,
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief ensure the handler has only one response, otherwise we'd have a leak
////////////////////////////////////////////////////////////////////////////////
@ -174,6 +144,7 @@ void HttpHandler::removePreviousResponse () {
////////////////////////////////////////////////////////////////////////////////
HttpResponse* HttpHandler::createResponse (HttpResponse::HttpResponseCode code) {
// avoid having multiple responses. this would be a memleak
removePreviousResponse();
@ -189,10 +160,6 @@ HttpResponse* HttpHandler::createResponse (HttpResponse::HttpResponseCode code)
return new HttpResponse(code, apiCompatibility);
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2009-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_HTTP_SERVER_HTTP_HANDLER_H
@ -46,11 +46,6 @@ namespace triagens {
// --SECTION-- class HttpHandler
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup HttpServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief abstract class for http handlers
////////////////////////////////////////////////////////////////////////////////
@ -60,19 +55,10 @@ namespace triagens {
HttpHandler (HttpHandler const&);
HttpHandler& operator= (HttpHandler const&);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -91,19 +77,10 @@ namespace triagens {
~HttpHandler ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -118,19 +95,10 @@ namespace triagens {
HttpResponse* stealResponse ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- Handler methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -170,19 +138,10 @@ namespace triagens {
// nothing by default
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- protected methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
@ -197,19 +156,10 @@ namespace triagens {
HttpResponse* createResponse (HttpResponse::HttpResponseCode);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- protected variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
@ -234,10 +184,6 @@ namespace triagens {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#endif
// -----------------------------------------------------------------------------

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -22,7 +22,7 @@
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2009-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2009-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#include "Handler.h"
@ -34,11 +34,6 @@ using namespace std;
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief constructor
////////////////////////////////////////////////////////////////////////////////
@ -53,19 +48,10 @@ Handler::Handler () {
Handler::~Handler () {
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup GeneralServer
/// @{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the job type
////////////////////////////////////////////////////////////////////////////////
@ -91,9 +77,13 @@ void Handler::setDispatcherThread (DispatcherThread*) {
}
////////////////////////////////////////////////////////////////////////////////
/// @}
/// @brief tries to cancel an execution
////////////////////////////////////////////////////////////////////////////////
bool Handler::cancel (bool running) {
return false;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -161,6 +161,12 @@ namespace triagens {
virtual status_t execute () = 0;
////////////////////////////////////////////////////////////////////////////////
/// @brief tries to cancel an execution
////////////////////////////////////////////////////////////////////////////////
virtual bool cancel (bool running);
////////////////////////////////////////////////////////////////////////////////
/// @brief handles error
////////////////////////////////////////////////////////////////////////////////

View File

@ -5,7 +5,7 @@
///
/// DISCLAIMER
///
/// Copyright 2004-2013 triAGENS GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS 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.
@ -23,7 +23,7 @@
///
/// @author Dr. Frank Celler
/// @author Achim Brandt
/// @author Copyright 2008-2013, triAGENS GmbH, Cologne, Germany
/// @author Copyright 2008-2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef TRIAGENS_REST_HTTP_RESPONSE_H
@ -38,11 +38,6 @@
// --SECTION-- class HttpResponse
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
namespace triagens {
namespace rest {
@ -59,19 +54,10 @@ namespace triagens {
HttpResponse (HttpResponse const&);
HttpResponse& operator= (HttpResponse const&);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public types
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -130,25 +116,16 @@ namespace triagens {
NOT_EXTENDED = 510
};
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- static public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the response is a HTTP HEAD response
////////////////////////////////////////////////////////////////////////////////
bool isHeadResponse () const {
return _isHeadResponse;
}
@ -176,19 +153,10 @@ namespace triagens {
static const string& getBatchErrorHeader ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- constructors and destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -206,19 +174,10 @@ namespace triagens {
virtual ~HttpResponse ();
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
public:
////////////////////////////////////////////////////////////////////////////////
@ -337,7 +296,7 @@ namespace triagens {
/// The name is automatically trimmed.
////////////////////////////////////////////////////////////////////////////////
void setCookie (string const& name, string const& value,
void setCookie (string const& name, string const& value,
int lifeTimeSeconds, string const& path, string const& domain,
@ -391,19 +350,10 @@ namespace triagens {
int deflate (size_t = 16384);
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
// -----------------------------------------------------------------------------
// --SECTION-- protected variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup Rest
/// @{
////////////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////////////
@ -435,7 +385,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
vector<char const*> _cookies;
////////////////////////////////////////////////////////////////////////////////
/// @brief body
////////////////////////////////////////////////////////////////////////////////
@ -457,10 +407,6 @@ namespace triagens {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @}
////////////////////////////////////////////////////////////////////////////////
#endif
// -----------------------------------------------------------------------------