#ifndef __ETCD_WATCHER_HPP__ #define __ETCD_WATCHER_HPP__ #include #include #include #include #include "etcd/Client.hpp" #include "etcd/Response.hpp" namespace etcd { class Watcher { public: Watcher(Client const &client, std::string const & key, std::function callback, bool recursive=false); Watcher(Client const &client, std::string const & key, std::string const &range_end, std::function callback); Watcher(Client const &client, std::string const & key, int64_t fromIndex, std::function callback, bool recursive=false); Watcher(Client const &client, std::string const & key, std::string const &range_end, int64_t fromIndex, std::function callback); Watcher(std::string const & address, std::string const & key, std::function callback, bool recursive=false); Watcher(std::string const & address, std::string const & key, std::string const &range_end, std::function callback); Watcher(std::string const & address, std::string const & key, int64_t fromIndex, std::function callback, bool recursive=false); Watcher(std::string const & address, std::string const & key, std::string const &range_end, int64_t fromIndex, std::function callback); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::function callback, bool recursive=false, int const auth_token_ttl = 300); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::string const &range_end, std::function callback, int const auth_token_ttl = 300); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, int64_t fromIndex, std::function callback, bool recursive=false, int const auth_token_ttl = 300); Watcher(std::string const & address, std::string const & username, std::string const & password, std::string const & key, std::string const &range_end, int64_t fromIndex, std::function callback, int const auth_token_ttl = 300); Watcher(Watcher const &) = delete; Watcher(Watcher &&) = delete; /** * Wait util the task has been stopped, actively or passively, e.g., the watcher * get cancelled or the server closes the connection. * * Returns true if the watcher is been normally cancalled, otherwise false. */ bool Wait(); /** * An async wait, the callback will be called when the task has been stopped. * * The callback parameter would be true if the watch is been normally cancalled. * If callback returns true, will reactivate the watcher and continue receiving * watch events, otherwise the watcher ends (default behaviour). */ void Wait(std::function callback); /** * Stop the watching action. * * Returns true if the watcher has been cancelled, otherwise false. */ bool Cancel(); ~Watcher(); protected: void doWatch(std::string const & key, std::string const & range_end, std::string const & auth_token, std::function callback); std::function callback; std::function wait_callback; // Don't use `pplx::task` to avoid sharing thread pool with other actions on the client // to avoid any potential blocking, which may block the keepalive loop and evict the lease. std::thread task_; struct EtcdServerStubs; struct EtcdServerStubsDeleter { void operator()(etcd::Watcher::EtcdServerStubs *stubs); }; std::unique_ptr stubs; private: int64_t fromIndex; bool recursive; std::atomic_bool cancelled; }; } #endif