1
0
Fork 0

Feature 3.4/add js isolate mem statistics (#9570)

This commit is contained in:
Wilfried Goesgens 2019-07-26 17:51:53 +02:00 committed by Jan
parent 1c8874fc6a
commit 19887387d1
12 changed files with 176 additions and 21 deletions

View File

@ -150,6 +150,7 @@ time the server is up and running
available physical memory on the server
@RESTSTRUCT{v8Context,server_statistics_struct,object,required,v8_context_struct}
Statistics about the V8 javascript contexts
@ -169,6 +170,26 @@ the number of V8 contexts that are free to use
the total number of V8 contexts we may spawn as configured by --javascript.v8-contexts
@RESTSTRUCT{memory,v8_context_struct,array,required,v8_isolate_memory}
a list of V8 memory / garbage collection watermarks; Refreshed on every garbage collection run;
Preserves min/max memory used at that time for 10 seconds
@RESTSTRUCT{contextId,v8_isolate_memory,integer,required,}
ID of the context this set of memory statistics is from
@RESTSTRUCT{tMax,v8_isolate_memory,number,required,}
the timestamp where the 10 seconds interval started
@RESTSTRUCT{countOfTimes,v8_isolate_memory,integer,required,}
how many times was the garbage collection run in these 10 seconds
@RESTSTRUCT{heapMax,v8_isolate_memory,integer,required,}
High watermark of all garbage collection runs in 10 seconds
@RESTSTRUCT{heapMin,v8_isolate_memory,integer,required,}
Low watermark of all garbage collection runs in these 10 seconds
@RESTSTRUCT{threads,server_statistics_struct,object,required,server_threads_struct}
Statistics about the server worker threads (excluding V8 specific or jemalloc specific threads and system threads)

View File

@ -361,11 +361,25 @@ void stats::Descriptions::serverStatistics(velocypack::Builder& b) const {
if (dealer->isEnabled()) {
b.add("v8Context", VPackValue(VPackValueType::Object, true));
auto v8Counters = dealer->getCurrentContextNumbers();
auto memoryStatistics = dealer->getCurrentMemoryNumbers();
b.add("available", VPackValue(v8Counters.available));
b.add("busy", VPackValue(v8Counters.busy));
b.add("dirty", VPackValue(v8Counters.dirty));
b.add("free", VPackValue(v8Counters.free));
b.add("max", VPackValue(v8Counters.max));
{
b.add("memory", VPackValue(VPackValueType::Array));
for (auto memStatistic : memoryStatistics) {
b.add(VPackValue(VPackValueType::Object));
b.add("contextId", VPackValue(memStatistic.id));
b.add("tMax", VPackValue(memStatistic.tMax));
b.add("countOfTimes", VPackValue(memStatistic.countOfTimes));
b.add("heapMax", VPackValue(memStatistic.heapMax));
b.add("heapMin", VPackValue(memStatistic.heapMin));
b.close();
}
b.close();
}
b.close();
}

View File

@ -924,15 +924,30 @@ void StatisticsWorker::generateRawStatistics(VPackBuilder& builder, double const
builder.add("v8Context", VPackValue(VPackValueType::Object));
V8DealerFeature::Statistics v8Counters{};
std::vector<V8DealerFeature::MemoryStatistics> memoryStatistics;
// V8 may be turned off on a server
if (dealer->isEnabled()) {
v8Counters = dealer->getCurrentContextNumbers();
memoryStatistics = dealer->getCurrentMemoryNumbers();
}
builder.add("available", VPackValue(v8Counters.available));
builder.add("busy", VPackValue(v8Counters.busy));
builder.add("dirty", VPackValue(v8Counters.dirty));
builder.add("free", VPackValue(v8Counters.free));
builder.add("max", VPackValue(v8Counters.max));
{
builder.add("memory", VPackValue(VPackValueType::Array));
for (auto memStatistic : memoryStatistics) {
builder.add(VPackValue(VPackValueType::Object));
builder.add("contextId", VPackValue(memStatistic.id));
builder.add("tMax", VPackValue(memStatistic.tMax));
builder.add("countOfTimes", VPackValue(memStatistic.countOfTimes));
builder.add("heapMax", VPackValue(memStatistic.heapMax));
builder.add("heapMin", VPackValue(memStatistic.heapMin));
builder.close();
}
builder.close();
}
builder.close();
builder.add("threads", VPackValue(VPackValueType::Object));

View File

@ -657,7 +657,9 @@ void V8DealerFeature::collectGarbage() {
context->assertLocked();
TRI_GET_GLOBALS();
v8g->_inForcedCollect = true;
TRI_RunGarbageCollectionV8(isolate, 1.0);
v8g->_inForcedCollect = false;
hasActiveExternals = v8g->hasActiveExternals();
}
localContext->Exit();
@ -1056,6 +1058,7 @@ void V8DealerFeature::cleanupLockedContext(V8Context* context) {
auto isolate = context->_isolate;
TRI_ASSERT(isolate != nullptr);
TRI_GET_GLOBALS();
context->assertLocked();
bool canceled = false;
@ -1070,7 +1073,9 @@ void V8DealerFeature::cleanupLockedContext(V8Context* context) {
{
v8::Context::Scope contextScope(localContext);
v8g->_inForcedCollect = true;
TRI_RunGarbageCollectionV8(isolate, availableTime);
v8g->_inForcedCollect = false;
}
// needs to be reset after the garbage collection
@ -1416,7 +1421,7 @@ V8Context* V8DealerFeature::buildContext(size_t id) {
{
v8::Context::Scope contextScope(localContext);
TRI_CreateV8Globals(isolate);
TRI_CreateV8Globals(isolate, id);
context->_context.Reset(context->_isolate, localContext);
if (context->_context.IsEmpty()) {
@ -1510,6 +1515,27 @@ V8DealerFeature::Statistics V8DealerFeature::getCurrentContextNumbers() {
_idleContexts.size(), _nrMaxContexts};
}
std::vector<V8DealerFeature::MemoryStatistics> V8DealerFeature::getCurrentMemoryNumbers() {
std::vector<V8DealerFeature::MemoryStatistics> result;
{
CONDITION_LOCKER(guard, _contextCondition);
result.reserve(_contexts.size());
for (auto oneCtx : _contexts) {
auto isolate = oneCtx->_isolate;
TRI_GET_GLOBALS();
result.push_back(MemoryStatistics
{
v8g->_id,
v8g->_lastMaxTime,
v8g->_countOfTimes,
v8g->_heapMax,
v8g->_heapLow
});
}
}
return result;
}
bool V8DealerFeature::loadJavaScriptFileInContext(TRI_vocbase_t* vocbase,
std::string const& file, V8Context* context,
VPackBuilder* builder) {
@ -1584,6 +1610,7 @@ void V8DealerFeature::shutdownContext(V8Context* context) {
V8ContextEntryGuard contextGuard(context);
v8::HandleScope scope(isolate);
TRI_GET_GLOBALS();
auto localContext = v8::Local<v8::Context>::New(isolate, context->_context);
localContext->Enter();
@ -1595,6 +1622,7 @@ void V8DealerFeature::shutdownContext(V8Context* context) {
[&isolate](TRI_action_t* action) { action->visit(isolate); });
double availableTime = 30.0;
v8g->_inForcedCollect = true;
if (RUNNING_ON_VALGRIND) {
// running under Valgrind
@ -1610,6 +1638,7 @@ void V8DealerFeature::shutdownContext(V8Context* context) {
} else {
TRI_RunGarbageCollectionV8(isolate, availableTime);
}
v8g->_inForcedCollect = false;
TRI_GET_GLOBALS();

View File

@ -50,6 +50,13 @@ class V8DealerFeature final : public application_features::ApplicationFeature {
size_t free;
size_t max;
};
struct MemoryStatistics {
size_t id;
double tMax;
size_t countOfTimes;
size_t heapMax;
size_t heapMin;
};
explicit V8DealerFeature(application_features::ApplicationServer& server);
@ -110,6 +117,7 @@ class V8DealerFeature final : public application_features::ApplicationFeature {
void setMaximumContexts(size_t nr) { _nrMaxContexts = nr; }
Statistics getCurrentContextNumbers();
std::vector<MemoryStatistics> getCurrentMemoryNumbers();
void defineBoolean(std::string const& name, bool value) {
_definedBooleans[name] = value;

View File

@ -124,6 +124,30 @@ static void JS_ServerStatistics(v8::FunctionCallbackInfo<v8::Value> const& args)
v8::Number::New(isolate, static_cast<int32_t>(v8Counters.free)));
v8CountersObj->Set(TRI_V8_ASCII_STRING(isolate, "max"),
v8::Number::New(isolate, static_cast<int32_t>(v8Counters.max)));
auto memoryStatistics = dealer->getCurrentMemoryNumbers();
v8::Handle<v8::Array> v8ListOfMemory = v8::Array::New(isolate, static_cast<int>(memoryStatistics.size()));
uint32_t pos = 0;
for (auto memStatistic : memoryStatistics) {
v8::Handle<v8::Object> v8MemStat = v8::Object::New(isolate);
v8MemStat->Set(TRI_V8_ASCII_STRING(isolate, "contextId"),
v8::Integer::New(isolate, static_cast<int32_t>(memStatistic.id)));
v8MemStat->Set(TRI_V8_ASCII_STRING(isolate, "tMax"),
v8::Number::New(isolate, (double)memStatistic.tMax));
v8MemStat->Set(TRI_V8_ASCII_STRING(isolate, "countOfTimes"),
v8::Integer::New(isolate, static_cast<int32_t>(memStatistic.countOfTimes)));
v8MemStat->Set(TRI_V8_ASCII_STRING(isolate, "heapMax"),
v8::Number::New(isolate, (double)memStatistic.heapMax));
v8MemStat->Set(TRI_V8_ASCII_STRING(isolate, "heapMin"),
v8::Number::New(isolate, (double)memStatistic.heapMin));
v8ListOfMemory->Set(pos++, v8MemStat);
}
v8CountersObj->Set(TRI_V8_ASCII_STRING(isolate, "memory"),
v8ListOfMemory);
result->Set(TRI_V8_ASCII_STRING(isolate, "v8Context"), v8CountersObj);
v8::Handle<v8::Object> counters = v8::Object::New(isolate);

View File

@ -22,8 +22,10 @@
#include "ApplicationFeatures/V8PlatformFeature.h"
#include "Basics/system-functions.h"
#include "Basics/MutexLocker.h"
#include "Basics/StringUtils.h"
#include "V8/v8-globals.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
@ -59,6 +61,7 @@ static void gcPrologueCallback(v8::Isolate* isolate, v8::GCType /*type*/,
static void gcEpilogueCallback(v8::Isolate* isolate, v8::GCType type,
v8::GCCallbackFlags flags) {
TRI_GET_GLOBALS();
static size_t const LIMIT_ABS = 200 * 1024 * 1024;
size_t minFreed = LIMIT_ABS / 10;
@ -69,6 +72,7 @@ static void gcEpilogueCallback(v8::Isolate* isolate, v8::GCType type,
v8::HeapStatistics h;
isolate->GetHeapStatistics(&h);
auto now = TRI_microtime();
size_t freed = 0;
size_t heapSizeAtStop = h.used_heap_size();
size_t heapSizeAtStart = V8PlatformFeature::getIsolateData(isolate)->_heapSizeAtStart;
@ -81,10 +85,29 @@ static void gcEpilogueCallback(v8::Isolate* isolate, v8::GCType type,
size_t usedHeadSize = h.used_heap_size();
size_t stillFree = heapSizeLimit - usedHeadSize;
if (now - v8g->_lastMaxTime > 10) {
v8g->_heapMax = heapSizeAtStart;
v8g->_heapLow = heapSizeAtStop;
v8g->_countOfTimes = 0;
v8g->_lastMaxTime = now;
} else {
v8g->_countOfTimes++;
if (heapSizeAtStart > v8g->_heapMax) {
v8g->_heapMax = heapSizeAtStart;
}
if (v8g->_heapLow > heapSizeAtStop) {
v8g->_heapLow = heapSizeAtStop;
}
}
if (stillFree <= LIMIT_ABS && freed <= minFreed) {
const char* whereFreed = (v8g->_inForcedCollect)? "Forced collect": "V8 internal collection";
LOG_TOPIC(WARN, arangodb::Logger::FIXME)
<< "reached heap-size limit, interrupting V8 execution ("
<< "heap size limit " << heapSizeLimit << ", used " << usedHeadSize << ")";
<< "reached heap-size limit of #" << v8g->_id
<< " interrupting V8 execution ("
<< "heap size limit " << heapSizeLimit
<< ", used " << usedHeadSize
<< ") during " << whereFreed;
isolate->TerminateExecution();
V8PlatformFeature::setOutOfMemory(isolate);

View File

@ -22,8 +22,9 @@
////////////////////////////////////////////////////////////////////////////////
#include "v8-globals.h"
#include "Basics/system-functions.h"
TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate)
TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate, size_t id)
: AgencyTempl(),
AgentTempl(),
ClusterInfoTempl(),
@ -126,7 +127,13 @@ TRI_v8_global_t::TRI_v8_global_t(v8::Isolate* isolate)
_vocbase(nullptr),
_activeExternals(0),
_canceled(false),
_allowUseDatabase(true) {
_allowUseDatabase(true),
_inForcedCollect(false),
_id(id),
_lastMaxTime(TRI_microtime()),
_countOfTimes(0),
_heapMax(0),
_heapLow(0) {
v8::HandleScope scope(isolate);
BufferConstant.Reset(isolate, TRI_V8_ASCII_STRING(isolate, "Buffer"));
@ -250,11 +257,11 @@ TRI_v8_global_t::DataSourcePersistent::~DataSourcePersistent() {
TRI_v8_global_t::~TRI_v8_global_t() {}
/// @brief creates a global context
TRI_v8_global_t* TRI_CreateV8Globals(v8::Isolate* isolate) {
TRI_v8_global_t* TRI_CreateV8Globals(v8::Isolate* isolate, size_t id) {
TRI_GET_GLOBALS();
TRI_ASSERT(v8g == nullptr);
v8g = new TRI_v8_global_t(isolate);
v8g = new TRI_v8_global_t(isolate, id);
isolate->SetData(arangodb::V8PlatformFeature::V8_DATA_SLOT, v8g);
return v8g;
@ -265,7 +272,7 @@ TRI_v8_global_t* TRI_GetV8Globals(v8::Isolate* isolate) {
TRI_GET_GLOBALS();
if (v8g == nullptr) {
v8g = TRI_CreateV8Globals(isolate);
v8g = TRI_CreateV8Globals(isolate, 0);
}
TRI_ASSERT(v8g != nullptr);

View File

@ -368,7 +368,7 @@ struct TRI_v8_global_t {
v8::Persistent<v8::External> _persistent;
};
explicit TRI_v8_global_t(v8::Isolate*);
explicit TRI_v8_global_t(v8::Isolate*, size_t id);
~TRI_v8_global_t();
@ -676,10 +676,24 @@ struct TRI_v8_global_t {
/// @brief whether or not useDatabase() is allowed
bool _allowUseDatabase;
/// @brief true if the arango infrastructure is garbage collecting
bool _inForcedCollect;
/// @brief the ID that identifies this v8 context
size_t const _id;
std::atomic<double> _lastMaxTime;
std::atomic<size_t> _countOfTimes;
std::atomic<size_t> _heapMax;
std::atomic<size_t> _heapLow;
};
/// @brief creates a global context
TRI_v8_global_t* TRI_CreateV8Globals(v8::Isolate*);
TRI_v8_global_t* TRI_CreateV8Globals(v8::Isolate*, size_t id);
/// @brief gets the global context
TRI_v8_global_t* TRI_GetV8Globals(v8::Isolate*);

View File

@ -114,9 +114,10 @@ TRI_Utf8ValueNFC::~TRI_Utf8ValueNFC() {
static void CreateErrorObject(v8::Isolate* isolate, int errorNumber,
std::string const& message) noexcept {
try {
TRI_GET_GLOBALS();
if (errorNumber == TRI_ERROR_OUT_OF_MEMORY) {
LOG_TOPIC(ERR, arangodb::Logger::FIXME)
<< "encountered out-of-memory error";
<< "encountered out-of-memory error in context #" << v8g->_id;
}
v8::Handle<v8::String> errorMessage = TRI_V8_STD_STRING(isolate, message);
@ -144,7 +145,6 @@ static void CreateErrorObject(v8::Isolate* isolate, int errorNumber,
v8::Number::New(isolate, errorNumber));
errorObject->Set(TRI_V8_STD_STRING(isolate, StaticStrings::ErrorMessage), errorMessage);
TRI_GET_GLOBALS();
TRI_GET_GLOBAL(ArangoErrorTempl, v8::ObjectTemplate);
v8::Handle<v8::Object> ArangoError = ArangoErrorTempl->NewInstance();

View File

@ -222,7 +222,7 @@ SECTION("test_collection_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = vocbase;
TRI_InitV8Users(context, vocbase, v8g.get(), isolate.get());

View File

@ -208,7 +208,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -311,7 +311,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -444,7 +444,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -580,7 +580,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -758,7 +758,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -967,7 +967,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -1117,7 +1117,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());
@ -1272,7 +1272,7 @@ SECTION("test_auth") {
v8::HandleScope handleScope(isolate.get()); // required for v8::Context::New(...), v8::ObjectTemplate::New(...) and TRI_AddMethodVocbase(...)
auto context = v8::Context::New(isolate.get());
v8::Context::Scope contextScope(context); // required for TRI_AddMethodVocbase(...)
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get())); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
std::unique_ptr<TRI_v8_global_t> v8g(TRI_CreateV8Globals(isolate.get(), 0)); // create and set inside 'isolate' for use with 'TRI_GET_GLOBALS()'
v8g->ArangoErrorTempl.Reset(isolate.get(), v8::ObjectTemplate::New(isolate.get())); // otherwise v8:-utils::CreateErrorObject(...) will fail
v8g->_vocbase = &vocbase;
auto arangoDBNS = v8::ObjectTemplate::New(isolate.get());