summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2016-04-23 12:15:02 -0400
committerAndrew Morrow <acm@mongodb.com>2016-06-16 17:54:40 -0400
commitdc73a4b9567e1ebdb6ba6c9a41a919a0c7c6adf0 (patch)
tree88422fbc7bb522c3765ef8d723385098a06f0413
parent0884bee06018f5f450b431cf6c5ac5eeeab6827a (diff)
downloadmongo-dc73a4b9567e1ebdb6ba6c9a41a919a0c7c6adf0.tar.gz
SERVER-23103 Make service contexts responsible for creating DBDirectClients
-rw-r--r--src/mongo/client/scoped_db_conn_test.cpp4
-rw-r--r--src/mongo/db/db.cpp12
-rw-r--r--src/mongo/db/dbdirectclient.cpp5
-rw-r--r--src/mongo/dbtests/framework.cpp14
-rw-r--r--src/mongo/s/server.cpp5
-rw-r--r--src/mongo/scripting/SConscript8
-rw-r--r--src/mongo/scripting/dbdirectclient_factory.cpp65
-rw-r--r--src/mongo/scripting/dbdirectclient_factory.h56
-rw-r--r--src/mongo/scripting/engine.cpp4
-rw-r--r--src/mongo/scripting/engine.h2
-rw-r--r--src/mongo/scripting/mozjs/mongo.cpp7
-rw-r--r--src/mongo/shell/clientAndShell.cpp4
-rw-r--r--src/mongo/unittest/crutch.cpp5
13 files changed, 152 insertions, 39 deletions
diff --git a/src/mongo/client/scoped_db_conn_test.cpp b/src/mongo/client/scoped_db_conn_test.cpp
index 5285217eeb9..9ee72a63953 100644
--- a/src/mongo/client/scoped_db_conn_test.cpp
+++ b/src/mongo/client/scoped_db_conn_test.cpp
@@ -67,10 +67,6 @@ using std::vector;
class Client;
class OperationContext;
-DBClientBase* createDirectClient(OperationContext* txn) {
- return NULL;
-}
-
namespace {
const string TARGET_HOST = "localhost:27017";
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 5b3b79bec1f..76701023439 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -109,6 +109,7 @@
#include "mongo/platform/process_id.h"
#include "mongo/s/balancer/balancer.h"
#include "mongo/s/sharding_initialization.h"
+#include "mongo/scripting/dbdirectclient_factory.h"
#include "mongo/scripting/engine.h"
#include "mongo/stdx/memory.h"
#include "mongo/stdx/thread.h"
@@ -530,8 +531,15 @@ static void _initAndListen(int listenPort) {
Client::initThread("initandlisten");
_initWireSpec();
- getGlobalServiceContext()->setFastClockSource(FastClockSourceFactory::create(Milliseconds(10)));
- getGlobalServiceContext()->setOpObserver(stdx::make_unique<OpObserver>());
+ auto globalServiceContext = getGlobalServiceContext();
+
+ globalServiceContext->setFastClockSource(FastClockSourceFactory::create(Milliseconds(10)));
+ globalServiceContext->setOpObserver(stdx::make_unique<OpObserver>());
+
+ DBDirectClientFactory::get(globalServiceContext)
+ .registerImplementation([](OperationContext* txn) {
+ return std::unique_ptr<DBClientBase>(new DBDirectClient(txn));
+ });
const repl::ReplSettings& replSettings = repl::getGlobalReplicationCoordinator()->getSettings();
diff --git a/src/mongo/db/dbdirectclient.cpp b/src/mongo/db/dbdirectclient.cpp
index 085291042f5..763b6e3dde2 100644
--- a/src/mongo/db/dbdirectclient.cpp
+++ b/src/mongo/db/dbdirectclient.cpp
@@ -46,11 +46,6 @@ namespace mongo {
using std::unique_ptr;
using std::string;
-// Called from scripting/engine.cpp and scripting/v8_db.cpp.
-DBClientBase* createDirectClient(OperationContext* txn) {
- return new DBDirectClient(txn);
-}
-
namespace {
class DirectClientScope {
diff --git a/src/mongo/dbtests/framework.cpp b/src/mongo/dbtests/framework.cpp
index db8815b1e90..8876cd5aa6e 100644
--- a/src/mongo/dbtests/framework.cpp
+++ b/src/mongo/dbtests/framework.cpp
@@ -38,11 +38,13 @@
#include "mongo/base/status.h"
#include "mongo/db/client.h"
#include "mongo/db/concurrency/lock_state.h"
+#include "mongo/db/dbdirectclient.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/db/service_context.h"
#include "mongo/db/service_context_d.h"
#include "mongo/dbtests/dbtests.h"
#include "mongo/dbtests/framework_options.h"
+#include "mongo/scripting/dbdirectclient_factory.h"
#include "mongo/scripting/engine.h"
#include "mongo/stdx/mutex.h"
#include "mongo/util/assert_util.h"
@@ -75,11 +77,19 @@ int runDbTests(int argc, char** argv) {
Client::initThread("testsuite");
+ auto globalServiceContext = getGlobalServiceContext();
+
+ // DBTests run as if in the database, so allow them to create direct clients.
+ DBDirectClientFactory::get(globalServiceContext)
+ .registerImplementation([](OperationContext* txn) {
+ return std::unique_ptr<DBClientBase>(new DBDirectClient(txn));
+ });
+
srand((unsigned)frameworkGlobalParams.seed);
printBuildInfo();
- checked_cast<ServiceContextMongoD*>(getGlobalServiceContext())->createLockFile();
- getGlobalServiceContext()->initializeGlobalStorageEngine();
+ checked_cast<ServiceContextMongoD*>(globalServiceContext)->createLockFile();
+ globalServiceContext->initializeGlobalStorageEngine();
int ret = unittest::Suite::run(frameworkGlobalParams.suites,
frameworkGlobalParams.filter,
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index ef167fe7d4f..c24b630994e 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -217,11 +217,6 @@ public:
}
};
-DBClientBase* createDirectClient(OperationContext* txn) {
- uassert(10197, "createDirectClient not implemented for sharding yet", 0);
- return nullptr;
-}
-
} // namespace mongo
using namespace mongo;
diff --git a/src/mongo/scripting/SConscript b/src/mongo/scripting/SConscript
index 3f1e034fa40..629b77c36f7 100644
--- a/src/mongo/scripting/SConscript
+++ b/src/mongo/scripting/SConscript
@@ -10,6 +10,7 @@ Import([
env.Library(
target='scripting_common',
source=[
+ 'dbdirectclient_factory.cpp',
'engine.cpp',
'utils.cpp',
],
@@ -20,11 +21,6 @@ env.Library(
'$BUILD_DIR/mongo/util/foundation',
'$BUILD_DIR/mongo/util/md5',
],
- LIBDEPS_TAGS=[
- # Depends on mongo::createDirectClient, which is not uniquely defined
- 'incomplete'
- ],
-
)
env.Library(
@@ -153,7 +149,7 @@ if usemozjs:
'$BUILD_DIR/mongo/db/service_context',
],
LIBDEPS_TAGS=[
- # Depends on haveLocalShardingInfo and createDirectClient, which are not
+ # Depends on haveLocalShardingInfo, which are not
# uniquely defined.
'incomplete',
],
diff --git a/src/mongo/scripting/dbdirectclient_factory.cpp b/src/mongo/scripting/dbdirectclient_factory.cpp
new file mode 100644
index 00000000000..a3180c4f1e8
--- /dev/null
+++ b/src/mongo/scripting/dbdirectclient_factory.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2016 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/platform/basic.h"
+
+#include "mongo/scripting/dbdirectclient_factory.h"
+
+#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/db/service_context.h"
+
+namespace mongo {
+
+namespace {
+
+const ServiceContext::Decoration<DBDirectClientFactory> forService =
+ ServiceContext::declareDecoration<DBDirectClientFactory>();
+
+} // namespace
+
+DBDirectClientFactory& DBDirectClientFactory::get(ServiceContext* context) {
+ fassert(40147, context);
+ return forService(context);
+}
+
+DBDirectClientFactory& DBDirectClientFactory::get(OperationContext* txn) {
+ fassert(40148, txn);
+ return get(txn->getServiceContext());
+}
+
+void DBDirectClientFactory::registerImplementation(Impl implementation) {
+ _implementation = std::move(implementation);
+}
+
+auto DBDirectClientFactory::create(OperationContext* txn) -> Result {
+ uassert(40149, "Cannot create a direct client in this context", _implementation);
+ return _implementation(txn);
+}
+
+} // namespace mongo
diff --git a/src/mongo/scripting/dbdirectclient_factory.h b/src/mongo/scripting/dbdirectclient_factory.h
new file mode 100644
index 00000000000..cf524e40849
--- /dev/null
+++ b/src/mongo/scripting/dbdirectclient_factory.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (C) 2016 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include "mongo/stdx/functional.h"
+
+namespace mongo {
+
+class DBClientBase;
+class OperationContext;
+class ServiceContext;
+
+class DBDirectClientFactory {
+public:
+ using Result = std::unique_ptr<DBClientBase>;
+ using Impl = stdx::function<Result(OperationContext*)>;
+
+ static DBDirectClientFactory& get(ServiceContext* service);
+ static DBDirectClientFactory& get(OperationContext* txn);
+
+ void registerImplementation(Impl implementation);
+ Result create(OperationContext* txn);
+
+private:
+ Impl _implementation;
+};
+
+} // namespace mongo
diff --git a/src/mongo/scripting/engine.cpp b/src/mongo/scripting/engine.cpp
index 392dcdc6e8b..7a843572551 100644
--- a/src/mongo/scripting/engine.cpp
+++ b/src/mongo/scripting/engine.cpp
@@ -41,6 +41,7 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/service_context.h"
#include "mongo/platform/unordered_set.h"
+#include "mongo/scripting/dbdirectclient_factory.h"
#include "mongo/util/file.h"
#include "mongo/util/log.h"
#include "mongo/util/text.h"
@@ -211,7 +212,8 @@ void Scope::loadStored(OperationContext* txn, bool ignoreNotConnected) {
_loadedVersion = lastVersion;
string coll = _localDBName + ".system.js";
- unique_ptr<DBClientBase> directDBClient(createDirectClient(txn));
+ auto directDBClient = DBDirectClientFactory::get(txn).create(txn);
+
unique_ptr<DBClientCursor> c =
directDBClient->query(coll, Query(), 0, 0, NULL, QueryOption_SlaveOk, 0);
massert(16669, "unable to get db client cursor from query", c.get());
diff --git a/src/mongo/scripting/engine.h b/src/mongo/scripting/engine.h
index 98384f1515a..df6760f9014 100644
--- a/src/mongo/scripting/engine.h
+++ b/src/mongo/scripting/engine.h
@@ -293,7 +293,5 @@ void installGlobalUtils(Scope& scope);
bool hasJSReturn(const std::string& s);
const char* jsSkipWhiteSpace(const char* raw);
-DBClientBase* createDirectClient(OperationContext* txn);
-
extern ScriptEngine* globalScriptEngine;
}
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp
index 1b7ce7dcd21..1fe567b03e6 100644
--- a/src/mongo/scripting/mozjs/mongo.cpp
+++ b/src/mongo/scripting/mozjs/mongo.cpp
@@ -37,6 +37,8 @@
#include "mongo/client/sasl_client_authenticate.h"
#include "mongo/client/sasl_client_session.h"
#include "mongo/db/namespace_string.h"
+#include "mongo/db/operation_context.h"
+#include "mongo/scripting/dbdirectclient_factory.h"
#include "mongo/scripting/mozjs/cursor.h"
#include "mongo/scripting/mozjs/implscope.h"
#include "mongo/scripting/mozjs/objectwrapper.h"
@@ -597,9 +599,8 @@ void MongoLocalInfo::construct(JSContext* cx, JS::CallArgs args) {
if (args.length() != 0)
uasserted(ErrorCodes::BadValue, "local Mongo constructor takes no args");
- std::unique_ptr<DBClientBase> conn;
-
- conn.reset(createDirectClient(scope->getOpContext()));
+ auto txn = scope->getOpContext();
+ auto conn = DBDirectClientFactory::get(txn).create(txn);
JS::RootedObject thisv(cx);
scope->getProto<MongoLocalInfo>().newObject(&thisv);
diff --git a/src/mongo/shell/clientAndShell.cpp b/src/mongo/shell/clientAndShell.cpp
index f1ecde12eeb..d4507a38d90 100644
--- a/src/mongo/shell/clientAndShell.cpp
+++ b/src/mongo/shell/clientAndShell.cpp
@@ -51,8 +51,4 @@ bool haveLocalShardingInfo(OperationContext* txn, const string& ns) {
return false;
}
-DBClientBase* createDirectClient(OperationContext* txn) {
- uassert(10256, "no createDirectClient in clientOnly", 0);
- return 0;
-}
}
diff --git a/src/mongo/unittest/crutch.cpp b/src/mongo/unittest/crutch.cpp
index 628aa7b589c..5f22f7cd4cc 100644
--- a/src/mongo/unittest/crutch.cpp
+++ b/src/mongo/unittest/crutch.cpp
@@ -45,11 +45,6 @@ class Client;
class OperationContext;
-DBClientBase* createDirectClient(OperationContext* txn) {
- fassertFailed(17249);
- return NULL;
-}
-
bool haveLocalShardingInfo(OperationContext* txn, const std::string& ns) {
return false;
}