diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-04-27 11:20:51 -0400 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-04-27 11:20:51 -0400 |
commit | c7d12379bcd047c923b72bd29ac99d05edfbb82a (patch) | |
tree | 6889312ed290fc923f974aaea3cc82d8371ec10b /src/mongo/scripting | |
parent | 69ba26c48be6a1ae334e6221765941a413e37bf5 (diff) | |
download | mongo-c7d12379bcd047c923b72bd29ac99d05edfbb82a.tar.gz |
SERVER-34665 Update definition of retryable error in the mongo shell.
Also exposes a way to explicitly trigger retargeting before the next
operation is run on the DBClientRS underlying a replica set connection
by calling ReplicaSetMonitor::failedHost().
Diffstat (limited to 'src/mongo/scripting')
-rw-r--r-- | src/mongo/scripting/mozjs/mongo.cpp | 49 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/mongo.h | 3 |
2 files changed, 49 insertions, 3 deletions
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp index 249792266a7..ba86facd270 100644 --- a/src/mongo/scripting/mozjs/mongo.cpp +++ b/src/mongo/scripting/mozjs/mongo.cpp @@ -31,10 +31,12 @@ #include "mongo/scripting/mozjs/mongo.h" #include "mongo/bson/simple_bsonelement_comparator.h" +#include "mongo/client/dbclient_rs.h" #include "mongo/client/dbclientinterface.h" #include "mongo/client/global_conn_pool.h" #include "mongo/client/mongo_uri.h" #include "mongo/client/native_sasl_client_session.h" +#include "mongo/client/replica_set_monitor.h" #include "mongo/client/sasl_client_authenticate.h" #include "mongo/client/sasl_client_session.h" #include "mongo/db/auth/sasl_command_constants.h" @@ -73,6 +75,7 @@ const JSFunctionSpec MongoBase::methods[] = { MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(insert, MongoLocalInfo, MongoExternalInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO( isReplicaSetConnection, MongoLocalInfo, MongoExternalInfo), + MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(_markNodeAsFailed, MongoExternalInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(logout, MongoLocalInfo, MongoExternalInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(remove, MongoLocalInfo, MongoExternalInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(runCommand, MongoLocalInfo, MongoExternalInfo), @@ -159,18 +162,23 @@ void setHiddenMongo(JSContext* cx, } else { scope->getProto<MongoExternalInfo>().newObject(&newMongo); } + + auto host = resPtr->getServerAddress(); JS_SetPrivate(newMongo, scope->trackedNew<std::shared_ptr<DBClientBase>>(std::move(resPtr))); ObjectWrapper from(cx, args.thisv()); ObjectWrapper to(cx, newMongo); - for (const auto& k : - {InternedString::slaveOk, InternedString::defaultDB, InternedString::host}) { + for (const auto& k : {InternedString::slaveOk, InternedString::defaultDB}) { JS::RootedValue tmpValue(cx); from.getValue(k, &tmpValue); to.setValue(k, tmpValue); } + // 'newMongo' is a direct connection to an individual server. Its "host" property therefore + // reports the stringified HostAndPort of the underlying DBClientConnection. + to.setString(InternedString::host, host); + JS::RootedValue value(cx); value.setObjectOrNull(newMongo); @@ -667,6 +675,43 @@ void MongoBase::Functions::isReplicaSetConnection::call(JSContext* cx, JS::CallA args.rval().setBoolean(conn->type() == ConnectionString::ConnectionType::SET); } +void MongoBase::Functions::_markNodeAsFailed::call(JSContext* cx, JS::CallArgs args) { + if (args.length() != 3) { + uasserted(ErrorCodes::BadValue, "_markNodeAsFailed needs 3 args"); + } + + if (!args.get(0).isString()) { + uasserted(ErrorCodes::BadValue, + "first argument to _markNodeAsFailed must be a stringified host and port"); + } + + if (!args.get(1).isNumber()) { + uasserted(ErrorCodes::BadValue, + "second argument to _markNodeAsFailed must be a numeric error code"); + } + + if (!args.get(2).isString()) { + uasserted(ErrorCodes::BadValue, + "third argument to _markNodeAsFailed must be a stringified reason"); + } + + auto* rsConn = dynamic_cast<DBClientReplicaSet*>(getConnection(args)); + if (!rsConn) { + uasserted(ErrorCodes::BadValue, "connection object isn't a replica set connection"); + } + + auto hostAndPort = ValueWriter(cx, args.get(0)).toString(); + auto code = ValueWriter(cx, args.get(1)).toInt32(); + auto reason = ValueWriter(cx, args.get(2)).toString(); + + const auto& replicaSetName = rsConn->getSetName(); + ReplicaSetMonitor::get(replicaSetName) + ->failedHost(HostAndPort(hostAndPort), + Status{static_cast<ErrorCodes::Error>(code), reason}); + + args.rval().setUndefined(); +} + void MongoLocalInfo::construct(JSContext* cx, JS::CallArgs args) { auto scope = getScope(cx); diff --git a/src/mongo/scripting/mozjs/mongo.h b/src/mongo/scripting/mozjs/mongo.h index 8c67677ddea..36fbc46a172 100644 --- a/src/mongo/scripting/mozjs/mongo.h +++ b/src/mongo/scripting/mozjs/mongo.h @@ -54,6 +54,7 @@ struct MongoBase : public BaseInfo { MONGO_DECLARE_JS_FUNCTION(getServerRPCProtocols); MONGO_DECLARE_JS_FUNCTION(insert); MONGO_DECLARE_JS_FUNCTION(isReplicaSetConnection); + MONGO_DECLARE_JS_FUNCTION(_markNodeAsFailed); MONGO_DECLARE_JS_FUNCTION(logout); MONGO_DECLARE_JS_FUNCTION(remove); MONGO_DECLARE_JS_FUNCTION(runCommand); @@ -67,7 +68,7 @@ struct MongoBase : public BaseInfo { MONGO_DECLARE_JS_FUNCTION(_startSession); }; - static const JSFunctionSpec methods[22]; + static const JSFunctionSpec methods[23]; static const char* const className; static const unsigned classFlags = JSCLASS_HAS_PRIVATE; |