1. 程式人生 > >mongo源碼學習(四)服務入口點ServiceEntryPoint

mongo源碼學習(四)服務入口點ServiceEntryPoint

() create 就是 pen -m ide dbr mongo pro

在上一篇博客mongo源碼學習(三)請求接收傳輸層中,稍微分析了一下TransportLayer的作用,這篇來看下ServiceEntryPoint是怎麽做的。

首先ServiceEntryPoint的定義在mongo/src/mongo/transport目錄下。

廢話不過說,直接上代碼。

service_entry_point.h

namespace mongo {

/**
 * This is the entrypoint from the transport layer into mongod or mongos.
 *
 * The ServiceEntryPoint accepts new Sessions from the TransportLayer, and is
 * responsible for running these Sessions in a get-Message, run-Message,
 * reply-with-Message loop.  It may not do this on the TransportLayer’s thread.
 
*/ /** * 這是從transport layer到mongod或者mongos的入口點。 * * ServiceEntryPoint從TransportLayer中接收新的Session,並且負責運行這些Sessions的 * get-Message,run-Message和reply-with-Message生命周期。它可能不會在TransportLayer的線程 * 中這些事情。 */ class ServiceEntryPoint { MONGO_DISALLOW_COPYING(ServiceEntryPoint); public: virtual ~ServiceEntryPoint() = default
; /** * Begin running a new Session. This method returns immediately. */ /** * 開始一個新的Session。這個方法會馬上返回。 */ virtual void startSession(transport::SessionHandle session) = 0; /** * End all sessions that do not match the mask in tags. */ /** * 結束所有和tags中掩碼不匹配的sessions。
*/ virtual void endAllSessions(transport::Session::TagMask tags) = 0; /** * Starts the service entry point */ /** * 啟動服務入口點。 */ virtual Status start() = 0; /** * Shuts down the service entry point. */ /** * 關閉服務入口點。 */ virtual bool shutdown(Milliseconds timeout) = 0; /** * Append high-level stats to a BSONObjBuilder for serverStatus */ /** * 為serverStatus向BSONObjBuilder追加高級狀態。 */ virtual void appendStats(BSONObjBuilder* bob) const = 0; /** * Returns the number of sessions currently open. */ /** * 返回當前打開的sessions數量。 */ virtual size_t numOpenSessions() const = 0; /** * Processes a request and fills out a DbResponse. */ /** * 處理一個請求並寫入DbResponse。 * P. S. 敲黑板了, 同誌們,這裏就是處理請求的地方了啊! */ virtual DbResponse handleRequest(OperationContext* opCtx, const Message& request) = 0; protected: ServiceEntryPoint() = default; }; } // namespace mongo

嗯,我覺得最重要的方法就是handleRequest了,接口中方法名字取的通俗易懂,沒毛病。

service_entry_pioint_impl.h

namespace mongo {
class ServiceContext;

namespace transport {
class Session;
}  // namespace transport

/**
 * A basic entry point from the TransportLayer into a server.
 *
 * The server logic is implemented inside of handleRequest() by a subclass.
 * startSession() spawns and detaches a new thread for each incoming connection
 * (transport::Session).
 */
/**
 * 從TransportLayer到server的一個基本入口點。
 *
 * 服務器處理請求的邏輯是通過子類的handleRequest()方法實現的。
 * startSession()會spawns並且分配一個新的線程來處理每個到來的連接(transport:Session)
 * spawn: (魚、蛙等)大量產(卵);引起,釀成
 *
 */
class ServiceEntryPointImpl : public ServiceEntryPoint {
    MONGO_DISALLOW_COPYING(ServiceEntryPointImpl);

public:
    // 構造函數
    explicit ServiceEntryPointImpl(ServiceContext* svcCtx);

    void startSession(transport::SessionHandle session) override;

    void endAllSessions(transport::Session::TagMask tags) final;

    Status start() final;
    bool shutdown(Milliseconds timeout) final;

    void appendStats(BSONObjBuilder* bob) const final;

    size_t numOpenSessions() const final {
        return _currentConnections.load();
    }

private:
    using SSMList = stdx::list<std::shared_ptr<ServiceStateMachine>>;
    using SSMListIterator = SSMList::iterator;

    ServiceContext* const _svcCtx;
    AtomicWord<std::size_t> _nWorkers;

    mutable stdx::mutex _sessionsMutex;
    stdx::condition_variable _shutdownCondition;
    SSMList _sessions;

    size_t _maxNumConnections{DEFAULT_MAX_CONN};
    AtomicWord<size_t> _currentConnections{0};
    AtomicWord<size_t> _createdConnections{0};

    std::unique_ptr<transport::ServiceExecutorReserved> _adminInternalPool;
};

/*
 * Returns true if a session with remote/local addresses should be exempted from maxConns
 */
/*
 * 如果遠程或本地的session可以從最大連接數約束中豁免則返回true
 */
bool shouldOverrideMaxConns(const transport::SessionHandle& session,
                            const std::vector<stdx::variant<CIDR, std::string>>& exemptions);

}  // namespace mongo

似乎也沒有太多好說的了。接下來的service_entry_point_impl.cpp是大頭,這裏開始要深入到方法內部去了。

service_entry_point_impl.cpp

mongo源碼學習(四)服務入口點ServiceEntryPoint