// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once #include "domainconfig.h" #include #include #include #include #include #include class FRT_Supervisor; class FNET_Transport; namespace search::common { class FileHeaderContext; } namespace search::transactionlog { class TransLogServerExplorer; class Domain; class TransLogServer : private FRT_Invokable, public WriterFactory { public: friend class TransLogServerExplorer; using SP = std::shared_ptr; using DomainSP = std::shared_ptr; TransLogServer(FNET_Transport & transport, const vespalib::string &name, int listenPort, const vespalib::string &baseDir, const common::FileHeaderContext &fileHeaderContext, const DomainConfig & cfg, size_t maxThreads); TransLogServer(FNET_Transport & transport, const vespalib::string &name, int listenPort, const vespalib::string &baseDir, const common::FileHeaderContext &fileHeaderContext, const DomainConfig & cfg); TransLogServer(FNET_Transport & transport, const vespalib::string &name, int listenPort, const vespalib::string &baseDir, const common::FileHeaderContext &fileHeaderContext); ~TransLogServer() override; DomainStats getDomainStats() const; std::shared_ptr getWriter(const vespalib::string & domainName) const override; TransLogServer & setDomainConfig(const DomainConfig & cfg); private: void request_stop(); void run(); void exportRPC(FRT_Supervisor & supervisor); void relayToThreadRPC(FRT_RPCRequest *req); void createDomain(FRT_RPCRequest *req); void deleteDomain(FRT_RPCRequest *req); void openDomain(FRT_RPCRequest *req); void listDomains(FRT_RPCRequest *req); void domainStatus(FRT_RPCRequest *req); void domainCommit(FRT_RPCRequest *req); void domainSessionRun(FRT_RPCRequest *req); void domainPrune(FRT_RPCRequest *req); void domainVisit(FRT_RPCRequest *req); void domainSessionClose(FRT_RPCRequest *req); void domainSync(FRT_RPCRequest *req); std::vector getDomainNames(); DomainSP findDomain(vespalib::stringref name) const; vespalib::string dir() const { return _baseDir + "/" + _name; } vespalib::string domainList() const { return dir() + "/" + _name + ".domains"; } using DomainList = std::map; using ReadGuard = std::shared_lock; using WriteGuard = std::unique_lock; bool running() const { return !_closed.load(std::memory_order_relaxed); } vespalib::string _name; vespalib::string _baseDir; DomainConfig _domainConfig; vespalib::ThreadStackExecutor _executor; std::thread _thread; std::unique_ptr _supervisor; DomainList _domains; mutable std::shared_mutex _domainMutex;; // Protects _domains std::condition_variable _domainCondition; std::mutex _fileLock; // Protects the creating and deleting domains including file system operations. document::Queue _reqQ; const common::FileHeaderContext &_fileHeaderContext; std::atomic _closed; }; }