diff --git a/arangod/V8Server/V8Job.cpp b/arangod/V8Server/V8Job.cpp index 3cbcfeef98..b55b3fe744 100644 --- a/arangod/V8Server/V8Job.cpp +++ b/arangod/V8Server/V8Job.cpp @@ -93,7 +93,7 @@ Job::status_t V8Job::work () { ApplicationV8::V8Context* context = _v8Dealer->enterContext(_vocbase, _allowUseDatabase); - // note: the context might be nullptr in case of shut-down + // note: the context might be 0 in case of shut-down if (context == nullptr) { return status_t(JOB_DONE); } @@ -113,44 +113,47 @@ Job::status_t V8Job::work () { v8::Handle action = v8::Local::Cast(function); - if (! action.IsEmpty()) { - // only go in here if action code can be compiled - v8::Handle fArgs; + if (action.IsEmpty()) { + _v8Dealer->exitContext(context); + // TODO: adjust exit code?? + return status_t(JOB_DONE); + } - if (_parameters != nullptr) { - fArgs = TRI_ObjectJson(isolate, _parameters); - } - else { - fArgs = v8::Undefined(isolate); - } + v8::Handle fArgs; - // call the function within a try/catch - try { - v8::TryCatch tryCatch; + if (_parameters != nullptr) { + fArgs = TRI_ObjectJson(isolate, _parameters); + } + else { + fArgs = v8::Undefined(isolate); + } - action->Call(current, 1, &fArgs); + // call the function within a try/catch + try { + v8::TryCatch tryCatch; - if (tryCatch.HasCaught()) { - if (tryCatch.CanContinue()) { - TRI_LogV8Exception(isolate, &tryCatch); - } - else { - TRI_GET_GLOBALS(); + action->Call(current, 1, &fArgs); - v8g->_canceled = true; - LOG_WARNING("caught non-catchable exception (aka termination) in periodic job"); - } + if (tryCatch.HasCaught()) { + if (tryCatch.CanContinue()) { + TRI_LogV8Exception(isolate, &tryCatch); + } + else { + TRI_GET_GLOBALS(); + + v8g->_canceled = true; + LOG_WARNING("caught non-catchable exception (aka termination) in periodic job"); } } - catch (triagens::basics::Exception const& ex) { - LOG_ERROR("caught exception in V8 job: %s %s", TRI_errno_string(ex.code()), ex.what()); - } - catch (std::bad_alloc const&) { - LOG_ERROR("caught exception in V8 job: %s", TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY)); - } - catch (...) { - LOG_ERROR("caught unknown exception in V8 job"); - } + } + catch (triagens::basics::Exception const& ex) { + LOG_ERROR("caught exception in V8 job: %s %s", TRI_errno_string(ex.code()), ex.what()); + } + catch (std::bad_alloc const&) { + LOG_ERROR("caught exception in V8 job: %s", TRI_errno_string(TRI_ERROR_OUT_OF_MEMORY)); + } + catch (...) { + LOG_ERROR("caught unknown exception in V8 job"); } } diff --git a/lib/Scheduler/AsyncTask.cpp b/lib/Scheduler/AsyncTask.cpp new file mode 100644 index 0000000000..2d96db8e8c --- /dev/null +++ b/lib/Scheduler/AsyncTask.cpp @@ -0,0 +1,97 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief tasks used to handle asynchronous events +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2014 ArangoDB 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. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Dr. Frank Celler +/// @author Achim Brandt +/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany +/// @author Copyright 2008-2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#include "AsyncTask.h" +#include "Basics/logging.h" +#include "Scheduler/Scheduler.h" + +using namespace triagens::rest; + +// ----------------------------------------------------------------------------- +// constructors and destructors +// ----------------------------------------------------------------------------- + +AsyncTask::AsyncTask () + : Task("AsyncTask"), + watcher(nullptr) { +} + +AsyncTask::~AsyncTask () { +} + +// ----------------------------------------------------------------------------- +// public methods +// ----------------------------------------------------------------------------- + +void AsyncTask::signal () { + _scheduler->sendAsync(watcher); +} + +// ----------------------------------------------------------------------------- +// Task methods +// ----------------------------------------------------------------------------- + +bool AsyncTask::setup (Scheduler* scheduler, + EventLoop loop) { + this->_scheduler = scheduler; + this->_loop = loop; + + // will throw if it goes wrong... + watcher = scheduler->installAsyncEvent(loop, this); + + return true; +} + +void AsyncTask::cleanup () { + if (_scheduler != nullptr) { + if (watcher != nullptr) { + _scheduler->uninstallEvent(watcher); + } + } + + watcher = nullptr; +} + +bool AsyncTask::handleEvent (EventToken token, EventType revents) { + if (watcher == token && (revents & EVENT_ASYNC)) { + return handleAsync(); + } + + return true; +} + +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}" +// End: diff --git a/lib/Scheduler/AsyncTask.h b/lib/Scheduler/AsyncTask.h new file mode 100644 index 0000000000..495fae8a02 --- /dev/null +++ b/lib/Scheduler/AsyncTask.h @@ -0,0 +1,119 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief tasks used to handle asynchronous events +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2014 ArangoDB 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. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Dr. Frank Celler +/// @author Achim Brandt +/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany +/// @author Copyright 2008-2013, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ARANGODB_SCHEDULER_ASYNC_TASK_H +#define ARANGODB_SCHEDULER_ASYNC_TASK_H 1 + +#include "Basics/Common.h" + +#include "Scheduler/Task.h" + +namespace triagens { + namespace rest { + +//////////////////////////////////////////////////////////////////////////////// +/// @brief task used to handle asyncs +//////////////////////////////////////////////////////////////////////////////// + + class AsyncTask : virtual public Task { + public: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief constructs a new task +//////////////////////////////////////////////////////////////////////////////// + + AsyncTask (); + + public: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief signals the task +/// +/// Note that this method can only be called after the task has been registered. +//////////////////////////////////////////////////////////////////////////////// + + void signal (); + + protected: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief destructor +//////////////////////////////////////////////////////////////////////////////// + + ~AsyncTask (); + + protected: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief handles the signal +//////////////////////////////////////////////////////////////////////////////// + + virtual bool handleAsync () = 0; + + protected: + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + + bool setup (Scheduler*, EventLoop) override; + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + + void cleanup () override; + +//////////////////////////////////////////////////////////////////////////////// +/// {@inheritDoc} +//////////////////////////////////////////////////////////////////////////////// + + bool handleEvent (EventToken, EventType) override; + + protected: + +//////////////////////////////////////////////////////////////////////////////// +/// @brief event for async signals +//////////////////////////////////////////////////////////////////////////////// + + EventToken watcher; + }; + } +} + +#endif +// ----------------------------------------------------------------------------- +// --SECTION-- END-OF-FILE +// ----------------------------------------------------------------------------- + +// Local Variables: +// mode: outline-minor +// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}" +// End: