summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/rwc_defaults_commands.cpp
diff options
context:
space:
mode:
authorJack Mulrow <jack.mulrow@mongodb.com>2019-12-17 22:55:38 +0000
committerevergreen <evergreen@mongodb.com>2019-12-17 22:55:38 +0000
commitceeb1a0402e2d0f6f0f55808c16a90e8b30f106c (patch)
tree85ed681451e9abd58212bc22f640415feaa74701 /src/mongo/db/commands/rwc_defaults_commands.cpp
parent61241bedf571481a89525ac26d311d3fed4108d6 (diff)
downloadmongo-ceeb1a0402e2d0f6f0f55808c16a90e8b30f106c.tar.gz
SERVER-43720 Make RWCDefaults commands persist the defaults
Diffstat (limited to 'src/mongo/db/commands/rwc_defaults_commands.cpp')
-rw-r--r--src/mongo/db/commands/rwc_defaults_commands.cpp52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/mongo/db/commands/rwc_defaults_commands.cpp b/src/mongo/db/commands/rwc_defaults_commands.cpp
index b6fb559c9a8..df4a0217d9c 100644
--- a/src/mongo/db/commands/rwc_defaults_commands.cpp
+++ b/src/mongo/db/commands/rwc_defaults_commands.cpp
@@ -33,14 +33,42 @@
#include "mongo/db/commands.h"
#include "mongo/db/commands/rwc_defaults_commands_gen.h"
+#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/namespace_string.h"
+#include "mongo/db/ops/write_ops.h"
#include "mongo/db/read_write_concern_defaults.h"
#include "mongo/db/repl/read_concern_args.h"
#include "mongo/db/repl/replication_coordinator.h"
+#include "mongo/db/rw_concern_default_gen.h"
+#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/util/log.h"
namespace mongo {
namespace {
+/**
+ * Replaces the persisted default read/write concern document with a new one representing the given
+ * defaults. Waits for the write concern on the given operation context to be satisfied before
+ * returning.
+ */
+void updatePersistedDefaultRWConcernDocument(OperationContext* opCtx, const RWConcernDefault& rw) {
+ DBDirectClient client(opCtx);
+ const auto commandResponse = client.runCommand([&] {
+ write_ops::Update updateOp(NamespaceString::kConfigSettingsNamespace);
+ updateOp.setUpdates({[&] {
+ write_ops::UpdateOpEntry entry;
+ entry.setQ(BSON("_id" << ReadWriteConcernDefaults::kPersistedDocumentId));
+ // Note the _id is propagated from the query into the upserted document.
+ entry.setU(rw.toBSON());
+ entry.setUpsert(true);
+ return entry;
+ }()});
+ return updateOp.serialize(
+ BSON(WriteConcernOptions::kWriteConcernField << opCtx->getWriteConcern().toBSON()));
+ }());
+ uassertStatusOK(getStatusFromWriteCommandReply(commandResponse->getCommandReply()));
+}
+
void assertNotStandaloneOrShardServer(OperationContext* opCtx, StringData cmdName) {
const auto replCoord = repl::ReplicationCoordinator::get(opCtx);
uassert(51300,
@@ -78,10 +106,20 @@ public:
assertNotStandaloneOrShardServer(opCtx, SetDefaultRWConcern::kCommandName);
auto& rwcDefaults = ReadWriteConcernDefaults::get(opCtx->getServiceContext());
- auto newDefaults = rwcDefaults.setConcerns(
+ auto newDefaults = rwcDefaults.generateNewConcerns(
opCtx, request().getDefaultReadConcern(), request().getDefaultWriteConcern());
- log() << "successfully set RWC defaults to " << newDefaults.toBSON();
- return newDefaults;
+
+ // TODO SERVER-44890 Remove this check once this command can only run on a primary node.
+ if (repl::ReplicationCoordinator::get(opCtx)->getMemberState() ==
+ repl::MemberState::RS_PRIMARY) {
+ // TODO SERVER-44890: Make this update invalidate the RWC cache through an
+ // OpObserver so setting the new values below is safe to be best effort.
+ updatePersistedDefaultRWConcernDocument(opCtx, newDefaults);
+ }
+
+ // Force a refresh to find the newly set defaults, then return them.
+ rwcDefaults.refreshIfNecessary(opCtx);
+ return rwcDefaults.getDefault(opCtx);
}
private:
@@ -121,9 +159,13 @@ public:
auto typedRun(OperationContext* opCtx) {
assertNotStandaloneOrShardServer(opCtx, GetDefaultRWConcern::kCommandName);
- // TODO SERVER-43720 Implement inMemory option.
-
auto& rwcDefaults = ReadWriteConcernDefaults::get(opCtx->getServiceContext());
+ if (request().getInMemory()) {
+ return rwcDefaults.getDefault(opCtx);
+ }
+
+ // Force a refresh to find the most recent defaults, then return them.
+ rwcDefaults.refreshIfNecessary(opCtx);
return rwcDefaults.getDefault(opCtx);
}