1
0
Fork 0

fixed shutdown for busy V8 contexts

This commit is contained in:
Frank Celler 2014-05-30 11:39:11 +02:00
parent 91e0f76082
commit c8ddff2a9b
7 changed files with 77 additions and 16 deletions

View File

@ -761,6 +761,7 @@ void ArangoServer::buildApplicationServer () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int ArangoServer::startupServer () { int ArangoServer::startupServer () {
OperationMode::server_operation_mode_e mode = OperationMode::determineMode(_applicationServer->programOptions());
// ............................................................................. // .............................................................................
// prepare the various parts of the Arango server // prepare the various parts of the Arango server
@ -783,8 +784,21 @@ int ArangoServer::startupServer () {
assert(vocbase != 0); assert(vocbase != 0);
// initialise V8 // initialise V8
size_t concurrency = _dispatcherThreads;
if (mode == OperationMode::MODE_CONSOLE) {
// one V8 instance is taken by the console
++concurrency;
}
else if (mode == OperationMode::MODE_UNITTESTS || mode == OperationMode::MODE_SCRIPT) {
if (concurrency == 1) {
// at least two to allow the test-runner and the scheduler to use a V8
concurrency = 2;
}
}
_applicationV8->setVocbase(vocbase); _applicationV8->setVocbase(vocbase);
_applicationV8->setConcurrency(_dispatcherThreads); _applicationV8->setConcurrency(concurrency);
if (_applicationServer->programOptions().has("upgrade")) { if (_applicationServer->programOptions().has("upgrade")) {
_applicationV8->performUpgrade(); _applicationV8->performUpgrade();
@ -855,8 +869,6 @@ int ArangoServer::startupServer () {
LOG_INFO("ArangoDB (version " TRI_VERSION_FULL ") is ready for business. Have fun!"); LOG_INFO("ArangoDB (version " TRI_VERSION_FULL ") is ready for business. Have fun!");
OperationMode::server_operation_mode_e mode = OperationMode::determineMode(_applicationServer->programOptions());
int res; int res;
if (mode == OperationMode::MODE_CONSOLE) { if (mode == OperationMode::MODE_CONSOLE) {

View File

@ -90,19 +90,20 @@ void ConsoleThread::run () {
try { try {
inner(); inner();
_applicationV8->exitContext(_context);
_done = 1;
} }
catch (const char*) { catch (const char*) {
_applicationV8->exitContext(_context);
_done = 1;
} }
catch (...) { catch (...) {
_applicationV8->exitContext(_context); _applicationV8->exitContext(_context);
_done = 1; _done = 1;
_applicationServer->beginShutdown();
throw; throw;
} }
_applicationV8->exitContext(_context);
_done = 1;
_applicationServer->beginShutdown();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -156,7 +157,6 @@ void ConsoleThread::inner () {
if (input == 0) { if (input == 0) {
_userAborted = true; _userAborted = true;
_applicationServer->beginShutdown();
// this will be caught by "run" // this will be caught by "run"
throw "user aborted"; throw "user aborted";

View File

@ -96,7 +96,6 @@ namespace triagens {
void userAbort () { void userAbort () {
_userAborted = true; _userAborted = true;
TRI_CLOSE(0);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -746,6 +746,25 @@ bool ApplicationV8::start () {
void ApplicationV8::close () { void ApplicationV8::close () {
_stopping = 1; _stopping = 1;
_contextCondition.broadcast(); _contextCondition.broadcast();
// unregister all tasks
if (_scheduler != nullptr) {
_scheduler->scheduler()->unregisterUserTasks();
}
// wait for all contexts to finish
for (size_t n = 0; n < 10 * 5; ++n) {
CONDITION_LOCKER(guard, _contextCondition);
if (_busyContexts.empty()) {
LOG_DEBUG("no busy V8 contexts");
break;
}
LOG_DEBUG("waiting for %d busy V8 contexts to finish", (int) _busyContexts.size());
guard.wait(100000);
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -753,9 +772,26 @@ void ApplicationV8::close () {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void ApplicationV8::stop () { void ApplicationV8::stop () {
// unregister all tasks
if (_scheduler != nullptr) { //send all busy contexts a termate signal
_scheduler->scheduler()->unregisterUserTasks(); {
CONDITION_LOCKER(guard, _contextCondition);
for (auto it = _busyContexts.begin(); it != _busyContexts.end(); ++it) {
LOG_WARNING("sending termination signal to V8 context");
v8::V8::TerminateExecution((*it)->_isolate);
}
}
// wait for one minute
for (size_t n = 0; n < 10 * 60; ++n) {
CONDITION_LOCKER(guard, _contextCondition);
if (_busyContexts.empty()) {
break;
}
guard.wait(100000);
} }
// stop GC // stop GC

View File

@ -114,7 +114,7 @@ static bool SyncDatafile (const TRI_datafile_t* const datafile,
return true; return true;
} }
assert(datafile->_fd > 0); assert(datafile->_fd >= 0);
if (begin == end) { if (begin == end) {
// no need to sync // no need to sync
@ -212,7 +212,7 @@ static void InitDatafile (TRI_datafile_t* datafile,
assert(fd == -1); assert(fd == -1);
} }
else { else {
assert(fd > 0); assert(fd >= 0);
} }
datafile->_state = TRI_DF_STATE_READ; datafile->_state = TRI_DF_STATE_READ;

View File

@ -214,6 +214,16 @@ bool ApplicationDispatcher::open () {
/// {@inheritDoc} /// {@inheritDoc}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void ApplicationDispatcher::close () {
if (_dispatcher != 0) {
_dispatcher->beginShutdown();
}
}
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void ApplicationDispatcher::stop () { void ApplicationDispatcher::stop () {
if (_dispatcherReporterTask != 0) { if (_dispatcherReporterTask != 0) {
_dispatcherReporterTask = 0; _dispatcherReporterTask = 0;
@ -222,8 +232,6 @@ void ApplicationDispatcher::stop () {
if (_dispatcher != 0) { if (_dispatcher != 0) {
static size_t const MAX_TRIES = 50; // 10 seconds (50 * 200 ms) static size_t const MAX_TRIES = 50; // 10 seconds (50 * 200 ms)
_dispatcher->beginShutdown();
for (size_t count = 0; count < MAX_TRIES && _dispatcher->isRunning(); ++count) { for (size_t count = 0; count < MAX_TRIES && _dispatcher->isRunning(); ++count) {
LOG_TRACE("waiting for dispatcher to stop"); LOG_TRACE("waiting for dispatcher to stop");
usleep(200 * 1000); usleep(200 * 1000);

View File

@ -136,6 +136,12 @@ namespace triagens {
bool open (); bool open ();
////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc}
////////////////////////////////////////////////////////////////////////////////
void close ();
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// {@inheritDoc} /// {@inheritDoc}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////