mirror of https://gitee.com/bigwinds/arangodb
if a cancelation has occured, flush the module cache
This commit is contained in:
parent
c2fa9cb091
commit
e436ecfa40
|
@ -1001,6 +1001,7 @@ int ArangoServer::runUnitTests (TRI_vocbase_t* vocbase) {
|
|||
cout << TRI_StringifyV8Exception(&tryCatch);
|
||||
}
|
||||
else {
|
||||
// will stop, so need for v8g->_canceled = true;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -1065,6 +1066,7 @@ int ArangoServer::runScript (TRI_vocbase_t* vocbase) {
|
|||
TRI_LogV8Exception(&tryCatch);
|
||||
}
|
||||
else {
|
||||
// will stop, so need for v8g->_canceled = true;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,7 +148,11 @@ namespace {
|
|||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public types
|
||||
// --SECTION-- class V8Context
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -208,6 +212,21 @@ void ApplicationV8::V8Context::handleGlobalContextMethods () {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the cancelation cleanup
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ApplicationV8::V8Context::handleCancelationCleanup () {
|
||||
v8::HandleScope scope;
|
||||
|
||||
LOG_DEBUG("executing cancelation cleanup context %d", (int) _id);
|
||||
|
||||
TRI_ExecuteJavaScriptString(_context,
|
||||
v8::String::New("require('internal').cleanupCancelation();"),
|
||||
v8::String::New("context cleanup method"),
|
||||
false);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- class ApplicationV8
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -360,10 +379,25 @@ void ApplicationV8::exitContext (V8Context* context) {
|
|||
// HasOutOfMemoryException must be called while there is still an isolate!
|
||||
bool const hasOutOfMemoryException = context->_context->HasOutOfMemoryException();
|
||||
|
||||
// check for cancelation requests
|
||||
bool const canceled = v8g->_canceled;
|
||||
v8g->_canceled = false;
|
||||
|
||||
// exit the context
|
||||
context->_context->Exit();
|
||||
context->_isolate->Exit();
|
||||
|
||||
// if the execution was canceled, we need to cleanup
|
||||
if (canceled) {
|
||||
context->_isolate->Enter();
|
||||
context->_context->Enter();
|
||||
|
||||
context->handleCancelationCleanup();
|
||||
|
||||
context->_context->Exit();
|
||||
context->_isolate->Exit();
|
||||
}
|
||||
|
||||
// try to execute new global context methods
|
||||
bool runGlobal = false;
|
||||
{
|
||||
|
|
|
@ -188,6 +188,12 @@ namespace triagens {
|
|||
|
||||
void handleGlobalContextMethods ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the cancelation cleanup
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void handleCancelationCleanup ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief mutex to protect _globalMethods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -150,7 +150,10 @@ Job::status_t V8Job::work () {
|
|||
TRI_LogV8Exception(&tryCatch);
|
||||
}
|
||||
else {
|
||||
LOG_WARNING("caught non-printable exception in periodic task");
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
LOG_WARNING("caught non-catchable exception (aka termination) in periodic job");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -730,6 +730,7 @@ static TRI_action_result_t ExecuteActionVocbase (TRI_vocbase_t* vocbase,
|
|||
}
|
||||
}
|
||||
else {
|
||||
v8g->_canceled = true;
|
||||
result.isValid = false;
|
||||
result.canceled = true;
|
||||
}
|
||||
|
|
|
@ -3499,6 +3499,9 @@ static v8::Handle<v8::Value> ExecuteQueryCursorAhuacatl (TRI_vocbase_t* const vo
|
|||
return scope.Close(v8::ThrowException(tryCatch.Exception()));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
@ -3847,6 +3850,9 @@ static v8::Handle<v8::Value> JS_Transaction (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(tryCatch.Exception()));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
@ -4489,6 +4495,9 @@ static v8::Handle<v8::Value> JS_NextGeneralCursor (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(tryCatch.Exception()));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
}
|
||||
|
@ -4566,6 +4575,9 @@ static v8::Handle<v8::Value> JS_ToArrayGeneralCursor (v8::Arguments const& argv)
|
|||
return scope.Close(v8::ThrowException(tryCatch.Exception()));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
}
|
||||
|
@ -5433,6 +5445,12 @@ static v8::Handle<v8::Value> JS_RunAhuacatl (v8::Arguments const& argv) {
|
|||
TRI_ObjectToString(tryCatch.Exception()).c_str());
|
||||
return scope.Close(v8::ThrowException(errorObject));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
||||
return scope.Close(result);
|
||||
|
@ -5562,6 +5580,9 @@ static v8::Handle<v8::Value> JS_ExplainAhuacatl (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(errorObject));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
@ -5636,6 +5657,9 @@ static v8::Handle<v8::Value> JS_ParseAhuacatl (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(errorObject));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2238,7 +2238,7 @@ var checkIfMayBeDropped = function(colName, graphName, graphs) {
|
|||
return;
|
||||
}
|
||||
var edgeDefinitions = graph.edgeDefinitions;
|
||||
if (graph.edgeDefinitions) {
|
||||
if (edgeDefinitions) {
|
||||
edgeDefinitions.forEach(
|
||||
function(edgeDefinition) {
|
||||
var from = edgeDefinition.from;
|
||||
|
@ -2257,7 +2257,7 @@ var checkIfMayBeDropped = function(colName, graphName, graphs) {
|
|||
var orphanCollections = graph.orphanCollections;
|
||||
if (orphanCollections) {
|
||||
if (orphanCollections.indexOf(colName) !== -1) {
|
||||
return false;
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -503,74 +503,80 @@ function require (path) {
|
|||
}
|
||||
|
||||
// create a new module
|
||||
var localModule = currentPackage.defineModule(
|
||||
id,
|
||||
"js",
|
||||
new Module(id, currentPackage, currentModule._applicationContext, path, origin, false));
|
||||
try {
|
||||
var localModule = currentPackage.defineModule(
|
||||
id,
|
||||
"js",
|
||||
new Module(id, currentPackage, currentModule._applicationContext, path, origin, false));
|
||||
|
||||
// create a new sandbox and execute
|
||||
var env = currentPackage._environment;
|
||||
// create a new sandbox and execute
|
||||
var env = currentPackage._environment;
|
||||
|
||||
var sandbox = {};
|
||||
sandbox.print = internal.print;
|
||||
var sandbox = {};
|
||||
sandbox.print = internal.print;
|
||||
|
||||
if (env !== undefined) {
|
||||
for (key in env) {
|
||||
if (env.hasOwnProperty(key) && key !== "__myenv__") {
|
||||
sandbox[key] = env[key];
|
||||
if (env !== undefined) {
|
||||
for (key in env) {
|
||||
if (env.hasOwnProperty(key) && key !== "__myenv__") {
|
||||
sandbox[key] = env[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var filename = fileUri2Path(origin);
|
||||
var filename = fileUri2Path(origin);
|
||||
|
||||
if (filename !== null) {
|
||||
sandbox.__filename = filename;
|
||||
sandbox.__dirname = normalizeModuleName(filename + "/..");
|
||||
}
|
||||
|
||||
sandbox.module = localModule;
|
||||
sandbox.exports = localModule.exports;
|
||||
|
||||
sandbox.require = function(path) {
|
||||
return localModule.require(path);
|
||||
};
|
||||
|
||||
if (localModule.hasOwnProperty("_applicationContext")) {
|
||||
sandbox.applicationContext = localModule._applicationContext;
|
||||
}
|
||||
|
||||
// try to execute the module source code
|
||||
var script = "(function (__myenv__) {";
|
||||
|
||||
for (key in sandbox) {
|
||||
if (sandbox.hasOwnProperty(key)) {
|
||||
script += "var " + key + " = __myenv__['" + key + "'];";
|
||||
if (filename !== null) {
|
||||
sandbox.__filename = filename;
|
||||
sandbox.__dirname = normalizeModuleName(filename + "/..");
|
||||
}
|
||||
|
||||
sandbox.module = localModule;
|
||||
sandbox.exports = localModule.exports;
|
||||
|
||||
sandbox.require = function(path) {
|
||||
return localModule.require(path);
|
||||
};
|
||||
|
||||
if (localModule.hasOwnProperty("_applicationContext")) {
|
||||
sandbox.applicationContext = localModule._applicationContext;
|
||||
}
|
||||
|
||||
// try to execute the module source code
|
||||
var script = "(function (__myenv__) {";
|
||||
|
||||
for (key in sandbox) {
|
||||
if (sandbox.hasOwnProperty(key)) {
|
||||
script += "var " + key + " = __myenv__['" + key + "'];";
|
||||
}
|
||||
}
|
||||
|
||||
script += "delete __myenv__;"
|
||||
+ content
|
||||
+ "\n});";
|
||||
|
||||
var fun = internal.executeScript(script, undefined, filename);
|
||||
|
||||
if (fun === undefined) {
|
||||
e = new Error("corrupted package '" + path
|
||||
+ "', cannot create module context function for: "
|
||||
+ script);
|
||||
|
||||
e.moduleNotFound = false;
|
||||
e._path = path;
|
||||
e._package = currentPackage.id;
|
||||
e._packageOrigin = currentPackage._origin;
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
fun(sandbox);
|
||||
|
||||
return localModule;
|
||||
}
|
||||
|
||||
script += "delete __myenv__;"
|
||||
+ content
|
||||
+ "\n});";
|
||||
|
||||
var fun = internal.executeScript(script, undefined, filename);
|
||||
|
||||
if (fun === undefined) {
|
||||
e = new Error("corrupted package '" + path
|
||||
+ "', cannot create module context function for: "
|
||||
+ script);
|
||||
|
||||
e.moduleNotFound = false;
|
||||
e._path = path;
|
||||
e._package = currentPackage.id;
|
||||
e._packageOrigin = currentPackage._origin;
|
||||
|
||||
throw e;
|
||||
catch (err) {
|
||||
currentPackage.clearModule(id, "js");
|
||||
throw err;
|
||||
}
|
||||
|
||||
fun(sandbox);
|
||||
|
||||
return localModule;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -903,6 +909,14 @@ function require (path) {
|
|||
|
||||
delete REGISTER_EXECUTE_FILE;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cleans up after cancelation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function cleanupCancelation () {
|
||||
module.unloadAll();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- Package
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1106,6 +1120,8 @@ function require (path) {
|
|||
internal[key] = EXPORTS_SLOW_BUFFER[key];
|
||||
}
|
||||
}
|
||||
|
||||
internal.cleanupCancelation = cleanupCancelation;
|
||||
}());
|
||||
|
||||
delete EXPORTS_SLOW_BUFFER;
|
||||
|
|
|
@ -85,6 +85,9 @@ v8::Handle<v8::Value> JSLoader::executeGlobalScript (v8::Handle<v8::Context> con
|
|||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(result);
|
||||
}
|
||||
}
|
||||
|
@ -121,6 +124,9 @@ bool JSLoader::loadScript (v8::Persistent<v8::Context> context, string const& na
|
|||
return false;
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
v8g->_canceled = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,6 +74,9 @@ TRI_js_exec_context_t* TRI_CreateExecutionContext (char const* script,
|
|||
ctx->_error = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
v8g->_canceled = true;
|
||||
ctx->_error = TRI_ERROR_REQUEST_CANCELED;
|
||||
}
|
||||
return ctx;
|
||||
|
@ -134,6 +137,9 @@ TRI_json_t* TRI_ExecuteResultContext (TRI_js_exec_context_t* ctx) {
|
|||
ctx->_error = TRI_ERROR_INTERNAL;
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
v8g->_canceled = true;
|
||||
ctx->_error = TRI_ERROR_REQUEST_CANCELED;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -128,9 +128,10 @@ TRI_v8_global_s::TRI_v8_global_s (v8::Isolate* isolate)
|
|||
_resolver(0),
|
||||
_server(0),
|
||||
_vocbase(0),
|
||||
_loader(0),
|
||||
_allowUseDatabase(true),
|
||||
_hasDeadObjects(false) {
|
||||
_hasDeadObjects(false),
|
||||
_loader(0),
|
||||
_canceled(false) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
BufferConstant = v8::Persistent<v8::String>::New(isolate, TRI_V8_SYMBOL("Buffer"));
|
||||
|
|
|
@ -746,12 +746,6 @@ typedef struct TRI_v8_global_s {
|
|||
|
||||
void* _vocbase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief pointer to the startup loader (JSLoader*)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* _loader;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not useDatabase() is allowed
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -764,6 +758,23 @@ typedef struct TRI_v8_global_s {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _hasDeadObjects;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- GENERAL
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief pointer to the startup loader (JSLoader*)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void* _loader;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief cancel has been caught
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool _canceled;
|
||||
|
||||
}
|
||||
TRI_v8_global_t;
|
||||
|
||||
|
|
|
@ -267,6 +267,11 @@ static bool LoadJavaScriptDirectory (char const* path,
|
|||
if (tryCatch.CanContinue()) {
|
||||
TRI_LogV8Exception(&tryCatch);
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
v8g->_canceled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,6 +423,9 @@ static v8::Handle<v8::Value> JS_Parse (v8::Arguments const& argv) {
|
|||
TRI_V8_SYNTAX_ERROR(scope, err.c_str());
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData());
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
}
|
||||
|
@ -828,6 +836,9 @@ static v8::Handle<v8::Value> JS_Execute (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(tryCatch.Exception()));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
}
|
||||
|
@ -846,6 +857,9 @@ static v8::Handle<v8::Value> JS_Execute (v8::Arguments const& argv) {
|
|||
return scope.Close(v8::ThrowException(tryCatch.Exception()));
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
}
|
||||
|
@ -3300,6 +3314,9 @@ v8::Handle<v8::Value> TRI_ExecuteJavaScriptString (v8::Handle<v8::Context> conte
|
|||
TRI_LogV8Exception(&tryCatch);
|
||||
}
|
||||
else {
|
||||
TRI_v8_global_t* v8g = (TRI_v8_global_t*) v8::Isolate::GetCurrent()->GetData();
|
||||
|
||||
v8g->_canceled = true;
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue