-
Type:
Task
-
Resolution: Unresolved
-
Priority:
Major - P3
-
None
-
Affects Version/s: None
-
Component/s: None
-
Replication
-
None
-
None
-
None
-
None
-
None
-
None
-
None
The following classes have public/open modularity visibility, even though the actual implementation details of the class are not relevant:
$ rg "MONGO_MOD_(PUB|OPEN) \w+(Impl|Mock)( |\$)" src/mongo/db/repl
src/mongo/db/repl/replication_coordinator_external_state_mock.h
67:class MONGO_MOD_PUB ReplicationCoordinatorExternalStateMock
src/mongo/db/repl/replication_coordinator_impl.h
185:class MONGO_MOD_PUB ReplicationCoordinatorImpl : public ReplicationCoordinator,
src/mongo/db/repl/replication_coordinator_external_state_impl.h
75:class MONGO_MOD_PUB ReplicationCoordinatorExternalStateImpl final
src/mongo/db/repl/replication_recovery.h
95:class MONGO_MOD_PUB ReplicationRecoveryImpl : public ReplicationRecovery {
src/mongo/db/repl/storage_interface_mock.h
100:class MONGO_MOD_PUB StorageInterfaceMock : public StorageInterface {
src/mongo/db/repl/replication_recovery_mock.h
39:class MONGO_MOD_PUB ReplicationRecoveryMock : public ReplicationRecovery {
src/mongo/db/repl/storage_interface_impl.h
62:class MONGO_MOD_OPEN StorageInterfaceImpl : public StorageInterface {
src/mongo/db/repl/data_replicator_external_state_impl.h
67:class MONGO_MOD_OPEN DataReplicatorExternalStateImpl : public DataReplicatorExternalState {
src/mongo/db/repl/replication_coordinator_mock.h
93:class MONGO_MOD_OPEN ReplicationCoordinatorMock : public ReplicationCoordinator {
For example, StorageInterfaceImpl has public visibility, so that people can write code like this:
#include "mongo/db/repl/storage_interface_impl.h" repl::StorageInterface::set(getServiceContext(), std::make_unique<repl::StorageInterfaceImpl>());
However, the only valid thing we expect people on other teams to do with a StorageInterfaceImpl or a StorageInterfaceMock is create it.
They need not even know of the existence of these classes. There should just be two factory functions that both return a pointer to StorageInterface, and one function should be named "mock" and another function should be named "impl".
By doing this we would:
- have a better separation of our public and private API
- make our code more readable
- use decorators to create or retrieve dependencies. For example, if we would normally unconditionally pass in a std::unique_ptr<StorageInterface>, then we would instead make that a default argument, and then make the default value would be something like this (for a mock interface):
std::unique_ptr<StorageInterface> defaultValue = [&]() { auto storageInterface = StorageInterface::get(svcCtx); if (storageInterface != nullptr) { return std::make_unique<StorageInterface>(storageInterface); } storageInterface = repl::mock::StorageInterface(svcCtx); StorageInterface::set(svcCtx); return storageInterface; }();
Below is an example of how this could simplify our code:
std::unique_ptr<repl::ReplicationCoordinator> AttachedServiceLifecycle::initializeReplicationCoordinator(ServiceContext* svcCtx) { auto storageInterface = repl::StorageInterface::get(svcCtx); auto replicationProcess = repl::ReplicationProcess::get(svcCtx); repl::TopologyCoordinator::Options topoCoordOptions; topoCoordOptions.maxSyncSourceLagSecs = Seconds(repl::maxSyncSourceLagSecs); topoCoordOptions.clusterRole = serverGlobalParams.clusterRole; return std::make_unique<repl::ReplicationCoordinatorImpl>( svcCtx, getGlobalReplSettings(), std::make_unique<repl::ReplicationCoordinatorExternalStateImpl>( svcCtx, storageInterface, replicationProcess), makeReplicationExecutor(svcCtx), std::make_unique<repl::TopologyCoordinator>(topoCoordOptions), replicationProcess, storageInterface, SecureRandom().nextInt64()); }
std::unique_ptr<repl::ReplicationCoordinator> AttachedServiceLifecycle::initializeReplicationCoordinator(ServiceContext* svcCtx) { repl::TopologyCoordinator::Options topoCoordOptions; topoCoordOptions.maxSyncSourceLagSecs = Seconds(repl::maxSyncSourceLagSecs); topoCoordOptions.clusterRole = serverGlobalParams.clusterRole; return repl::impl::ReplicationCoordinator( svcCtx, // note: replication coordinator external state deduced to be impl repl::impl::TopologyCoordinator(topoCoordOptions)); }