MongoDB核心類之service_context.h: mongo::ServiceContext

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內部字段

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啓動,各核心類之間的關係

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章