MongoDB核心類之service_context.h: mongo::ServiceContext
目錄
MongoDB核心類之service_context.h: mongo::ServiceContext
ServiceContext的內部類:客戶端觀察者:ClientObserver
ServiceContext內部類:LockedClientsCursor,用來枚舉ServiceContext中的所有Client。
ServiceContext內部類:刪除ServiceContext的接口ServiceContextDeleter
ServiceContext內部類:刪除客戶端Client對象的接口:ClientDeleter
ServiceContext內部類:刪除OperationContext類的接口:OperationContextDeleter
ServiceContext內部接口:ServiceContext的構造和釋放
ServiceContext內部類:構建時動作註冊:ConstructorActionRegisterer
ServiceContext內部類:用來持有ClientObserver的ClientObserverHolder
ServiceContext的字段:與上邊操作分開了,實際上是一個類裏的
ServiceEntryPoint和ServiceStateMachine以及ServiceExecutor之間的關係如下
ServiceContext代表了一個mongodb服務器。 比如一個mongod服務器, 或者一個mongos路由(分片模式下)。ServiceContext是Context繼承關係中的根結點。ServiceContext擁有0個或者多個客戶端(client), 每個客戶端擁有各自的OperationContexts.
源碼版本:
mongo$ git log
commit 85707dafe1d2894505fdcf74336f93ed7a5f6636
Author: dalyd <[email protected]>
Date: Fri Jun 19 11:22:47 2020 -0400
SERVER-49807 Use modules for Linkbench2
ServiceContext的內部類:客戶端觀察者:ClientObserver
創建方法:在service->makeClient()創建後會創建ClientObserver對象。作爲觀察者,預定義了以下幾個事件。
class ClientObserver {
public:
virtual ~ClientObserver() = default;
virtual void onCreateClient(Client* client) = 0;
virtual void onDestroyClient(Client* client) = 0;
virtual void onCreateOperationContext(OperationContext* opCtx) = 0;
virtual void onDestroyOperationContext(OperationContext* opCtx) = 0;
};
ServiceContext內部類:LockedClientsCursor,用來枚舉ServiceContext中的所有Client。
class LockedClientsCursor {
public:
explicit LockedClientsCursor(ServiceContext* service);
Client* next();
private:
stdx::unique_lock<Latch> _lock;
ClientSet::const_iterator _curr;
ClientSet::const_iterator _end;
};
Client* ServiceContext::LockedClientsCursor::next() {
if (_curr == _end)
return nullptr;
Client* result = *_curr;
++_curr;
return result;
}
ServiceContext內部類:刪除ServiceContext的接口ServiceContextDeleter
class ServiceContextDeleter {
public:
void operator()(ServiceContext* service) const;
};
//爲unique_ptr的對象指定析構器
using UniqueServiceContext = std::unique_ptr<ServiceContext, ServiceContextDeleter>;
ServiceContext內部類:刪除客戶端Client對象的接口:ClientDeleter
class ClientDeleter {
public:
void operator()(Client* client) const;
};
//定義Unique類型,提供客戶端釋放函數
using UniqueClient = std::unique_ptr<Client, ClientDeleter>;
ServiceContext內部類:刪除OperationContext類的接口:OperationContextDeleter
class OperationContextDeleter {
public:
void operator()(OperationContext* opCtx) const;
};
using UniqueOperationContext = std::unique_ptr<OperationContext, OperationContextDeleter>;
ServiceContext內部接口:ServiceContext的構造和釋放
using ConstructorAction = std::function<void(ServiceContext*)>;
using DestructorAction = std::function<void(ServiceContext*)>;
class ConstructorDestructorActions {
public:
ConstructorDestructorActions(ConstructorAction constructor, DestructorAction destructor)
: _constructor(std::move(constructor)), _destructor(std::move(destructor)) {}
void onCreate(ServiceContext* service) const {
_constructor(service);
}
void onDestroy(ServiceContext* service) const {
_destructor(service);
}
private:
ConstructorAction _constructor;
DestructorAction _destructor;
};
ServiceContext內部類:構建時動作註冊:ConstructorActionRegisterer
class ConstructorActionRegisterer { //構造時的動作註冊
public:
ConstructorActionRegisterer(std::string name,
ConstructorAction constructor,
DestructorAction destructor = {});
//構造動作會關聯一個名字
//constructor在所有prereqs執行成功後。然後執行對應的destructor(如果有提供,可以不提供)
ConstructorActionRegisterer(std::string name,
std::vector<std::string> prereqs,
ConstructorAction constructor,
DestructorAction destructor = {});
//先執行preqs,再執行constructor,再執行最後執行depends,再執行destructor.
ConstructorActionRegisterer(std::string name,
std::vector<std::string> prereqs,
std::vector<std::string> dependents,
ConstructorAction constructor,
DestructorAction destructor = {});
private:
using ConstructorActionListIterator = std::list<ConstructorDestructorActions>::iterator;
ConstructorActionListIterator _iter;
//全局註冊器
boost::optional<GlobalInitializerRegisterer> _registerer;
};
ServiceContext內部類:用來持有ClientObserver的ClientObserverHolder
class ClientObserverHolder {
public:
void onCreate(Client* client) const {
_observer->onCreateClient(client);
}
void onDestroy(Client* client) const {
_observer->onDestroyClient(client);
}
void onCreate(OperationContext* opCtx) const {
_observer->onCreateOperationContext(opCtx);
}
void onDestroy(OperationContext* opCtx) const {
_observer->onDestroyOperationContext(opCtx);
}
/*explicit*/ ClientObserverHolder(std::unique_ptr<ClientObserver> observer)
: _observer(std::move(observer)) {}
private:
std::unique_ptr<ClientObserver> _observer;
};
ServiceContext內部字段
class ServiceContext final : public Decorable<ServiceContext> {
//可見不能直接構造ServiceContext對象。此對象也不能拷貝。構造函數和賦值操作都被刪除了。
ServiceContext(const ServiceContext&) = delete;
ServiceContext& operator=(const ServiceContext&) = delete;
public:
using ClientSet = stdx::unordered_set<Client*>;
//構建ServiceContext的工廠函數
static UniqueServiceContext make();
ServiceContext();
~ServiceContext();
//註冊客戶端觀察者:只能在makeClient中調用,或者在啓動多線程前
void registerClientObserver(std::unique_ptr<ClientObserver> observer);
//創建一個客戶端Client對象,session是transport裏的SessionHandle對象,此對象用來與客戶端交互
UniqueClient makeClient(std::string desc, transport::SessionHandle session = nullptr);
//創建一個操作上下文,此時client不能有OperationContext
UniqueOperationContext makeOperationContext(Client* client);
//設置存儲引擎 In-Memory WireTiger?
void setStorageEngine(std::unique_ptr<StorageEngine> engine);
StorageEngine* getStorageEngine() {
return _storageEngine.get();
}
//信號處理,通知所有的OperationContext已經被Kill了
void setKillAllOperations();
void unsetKillAllOperations();
bool getKillAllOperations() {
return _globalKill.loadRelaxed();
}
//處理信號,默認值是ctrl+C. 操作前要先獲取 opCtx->getClient, and opCtx->getServiceContext() 的鎖。遍歷_killOpListeners,調用其interrupt方法。
void killOperation(WithLock,
OperationContext* opCtx,
ErrorCodes::Error killCode = ErrorCodes::Interrupted);
void killAndDelistOperation(
OperationContext* opCtx,
ErrorCodes::Error killError = ErrorCodes::OperationIsKilledAndDelisted) noexcept;
//註冊信號處理器
void registerKillOpListener(KillOpListenerInterface* listener);
//設置週期化運行的函數,在設置前必須已經在運行了。ServiceContext不負責啓動runner
void setPeriodicRunner(std::unique_ptr<PeriodicRunner> runner);
PeriodicRunner* getPeriodicRunner() const;
//transport
transport::TransportLayer* getTransportLayer() const;
ServiceEntryPoint* getServiceEntryPoint() const;
transport::ServiceExecutor* getServiceExecutor() const; //一個調度器,可以把任務調度到線程上運行
void setServiceEntryPoint(std::unique_ptr<ServiceEntryPoint> sep);
void setTransportLayer(std::unique_ptr<transport::TransportLayer> tl);
void setServiceExecutor(std::unique_ptr<transport::ServiceExecutor> exec);
//阻塞,等所有transportLayer都添加完成
void waitForStartupComplete();
//通知所有TransportLayer啓動完成
void notifyStartupComplete();
int getActiveClientOperations();
void setOpObserver(std::unique_ptr<OpObserver> opObserver);
OpObserver* getOpObserver() const {
return _opObserver.get();
}
//GET SET幾種時鐘源
TickSource* getTickSource() const {
return _tickSource.get();
}
ClockSource* getFastClockSource() const {
return _fastClockSource.get();
}
ClockSource* getPreciseClockSource() const {
return _preciseClockSource.get();
}
//延時執行器
BatonHandle makeBaton(OperationContext* opCtx) const;
uint64_t getCatalogGeneration() const {
return _catalogGeneration.load();
}
void incrementCatalogGeneration() {
_catalogGeneration.fetchAndAdd(1);
}
LockedClient getLockedClient(OperationId id);
//移除opCtx上的操作,要獲得Client的鎖
void _delistOperation(OperationContext* opCtx) noexcept;
};
ServiceContext的字段:與上邊操作分開了,實際上是一個類裏的
class ServiceContext final : public Decorable<ServiceContext>
{
//ServiceContext級別的鎖
Mutex _mutex = MONGO_MAKE_LATCH(/*HierarchicalAcquisitionLevel(2), */
"ServiceContext::_mutex");
std::unique_ptr<PeriodicRunner> _runner;
//傳輸層,也就是網絡接口,用來接受客戶端連接
std::unique_ptr<transport::TransportLayer> _transportLayer;
//這裏註冊各種命令,mongos和mongod顯示能處理的命令不同
std::unique_ptr<ServiceEntryPoint> _serviceEntryPoint;
std::unique_ptr<transport::ServiceExecutor> _serviceExecutor;
std::unique_ptr<StorageEngine> _storageEngine;
std::vector<ClientObserverHolder> _clientObservers;
ClientSet _clients; //所有的clients都放在這個set裏
//OperationId到Client的映射
stdx::unordered_map<OperationId, Client*> _clientByOperationId;
std::unique_ptr<OpObserver> _opObserver;
std::unique_ptr<TickSource> _tickSource;
//不精確,但是調用成本低
std::unique_ptr<ClockSource> _fastClockSource;
//高精確度,但是調用成本高
std::unique_ptr<ClockSource> _preciseClockSource;
AtomicWord<bool> _globalKill{false};
std::vector<KillOpListenerInterface*> _killOpListeners;
//用來分配操作ID
AtomicWord<OperationId> _nextOpId{1};
AtomicWord<uint64_t> _catalogGeneration{0};
bool _startupComplete = false;
stdx::condition_variable _startupCompleteCondVar;
};
ServiceEntryPoint和ServiceStateMachine以及ServiceExecutor之間的關係如下
更加詳細的關係見我的另一篇:mongodb之mongod啓動,各核心類之間的關係