summaryrefslogtreecommitdiff
path: root/src/mongo/scripting
diff options
context:
space:
mode:
authorA. Jesse Jiryu Davis <jesse@mongodb.com>2018-12-12 11:16:13 -0500
committerA. Jesse Jiryu Davis <jesse@mongodb.com>2019-01-07 22:54:19 -0500
commit09fdd6cd55bfaca9ac525f6a0668ed97a7f3d048 (patch)
treed402ff485f3ca1c26ad23535867c6525a6c40268 /src/mongo/scripting
parentc2892222a633609fd14706062d8ed6086352004d (diff)
downloadmongo-09fdd6cd55bfaca9ac525f6a0668ed97a7f3d048.tar.gz
SERVER-38510 Set moreToCome flag with OP_MSG writes from shell
Diffstat (limited to 'src/mongo/scripting')
-rw-r--r--src/mongo/scripting/mozjs/mongo.cpp48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/mongo/scripting/mozjs/mongo.cpp b/src/mongo/scripting/mozjs/mongo.cpp
index 734e6b562b7..5188c0f3888 100644
--- a/src/mongo/scripting/mozjs/mongo.cpp
+++ b/src/mongo/scripting/mozjs/mongo.cpp
@@ -110,6 +110,23 @@ DBClientBase* getConnection(JS::CallArgs& args) {
return getConnectionRef(args).get();
}
+bool isUnacknowledged(const BSONObj& cmdObj) {
+ auto wc = cmdObj["writeConcern"];
+ return wc && wc["w"].isNumber() && wc["w"].safeNumberLong() == 0;
+}
+
+void returnOk(JSContext* cx, JS::CallArgs& args) {
+ ValueReader(cx, args.rval()).fromBSON(BSON("ok" << 1), nullptr, false);
+}
+
+void runFireAndForgetCommand(const std::shared_ptr<DBClientBase>& conn,
+ const std::string& database,
+ BSONObj body,
+ const BSONObj& extraFields = {}) {
+ auto request = OpMsgRequest::fromDBAndBody(database, body, extraFields);
+ conn->runFireAndForgetCommand(request);
+}
+
void setCursor(MozJSImplScope* scope,
JS::HandleObject target,
std::unique_ptr<DBClientCursor> cursor,
@@ -135,6 +152,17 @@ void setCursorHandle(MozJSImplScope* scope,
scope->trackedNew<CursorHandleInfo::CursorTracker>(std::move(ns), cursorId, *client));
}
+void setHiddenMongo(JSContext* cx, JS::HandleValue value, JS::CallArgs& args) {
+ ObjectWrapper o(cx, args.rval());
+ if (!o.hasField(InternedString::_mongo)) {
+ o.defineProperty(InternedString::_mongo, value, JSPROP_READONLY | JSPROP_PERMANENT);
+ }
+}
+
+void setHiddenMongo(JSContext* cx, JS::CallArgs& args) {
+ setHiddenMongo(cx, args.thisv(), args);
+}
+
void setHiddenMongo(JSContext* cx,
std::shared_ptr<DBClientBase> resPtr,
DBClientBase* origConn,
@@ -143,7 +171,7 @@ void setHiddenMongo(JSContext* cx,
// If the connection that ran the command is the same as conn, then we set a hidden "_mongo"
// property on the returned object that is just "this" Mongo object.
if (resPtr.get() == origConn) {
- o.defineProperty(InternedString::_mongo, args.thisv(), JSPROP_READONLY | JSPROP_PERMANENT);
+ setHiddenMongo(cx, args.thisv(), args);
} else {
JS::RootedObject newMongo(cx);
@@ -168,8 +196,7 @@ void setHiddenMongo(JSContext* cx,
JS::RootedValue value(cx);
value.setObjectOrNull(newMongo);
-
- o.defineProperty(InternedString::_mongo, value, JSPROP_READONLY | JSPROP_PERMANENT);
+ setHiddenMongo(cx, value, args);
}
}
} // namespace
@@ -212,6 +239,13 @@ void MongoBase::Functions::runCommand::call(JSContext* cx, JS::CallArgs args) {
BSONObj cmdObj = ValueWriter(cx, args.get(1)).toBSON();
+ if (isUnacknowledged(cmdObj)) {
+ runFireAndForgetCommand(conn, database, cmdObj);
+ setHiddenMongo(cx, args);
+ returnOk(cx, args);
+ return;
+ }
+
int queryOptions = ValueWriter(cx, args.get(2)).toInt32();
BSONObj cmdRes;
auto resTuple = conn->runCommandWithTarget(database, cmdObj, cmdRes, conn, queryOptions);
@@ -244,6 +278,14 @@ void MongoBase::Functions::runCommandWithMetadata::call(JSContext* cx, JS::CallA
BSONObj commandArgs = ValueWriter(cx, args.get(2)).toBSON();
const auto& conn = getConnectionRef(args);
+
+ if (isUnacknowledged(commandArgs)) {
+ runFireAndForgetCommand(conn, database, commandArgs, metadata);
+ setHiddenMongo(cx, args);
+ returnOk(cx, args);
+ return;
+ }
+
auto resTuple = conn->runCommandWithTarget(
OpMsgRequest::fromDBAndBody(database, commandArgs, metadata), conn);
auto res = std::move(std::get<0>(resTuple));