![]() |
boost::taar::context_store — Thread-safe keyed store of context objects with idle expiry and per-entry serialisation.
// In header: <boost/taar/core/context_store.hpp> template<typename Key, typename Context> class context_store { public: // types typedef Key key_type; typedef Context context_type; typedef std::chrono::steady_clock clock; typedef clock::duration duration; typedef clock::time_point time_point; typedef std::function< Key()> key_generator; typedef std::function< time_point()> clock_function; typedef std::shared_ptr< entry > entry_ptr; // member classes/structs/unions // One stored context with its bookkeeping. Obtain through find, emplace or create. class entry { public: // public member functions entry(Key, std::shared_ptr< Context >, time_point); Key const & key() const noexcept; std::shared_ptr< Context > const & context() const noexcept; time_point last_activity() const noexcept; bool in_flight() const noexcept; }; // Releases an entry's lock (and refreshes its activity) on destruction. class lock_guard { public: // public member functions lock_guard() = default; lock_guard(lock_guard const &) = delete; lock_guard & operator=(lock_guard const &) = delete; lock_guard(lock_guard &&) noexcept; lock_guard & operator=(lock_guard &&) noexcept; ~lock_guard(); entry_ptr const & get() const noexcept; explicit operator bool() const noexcept; }; // public member functions explicit context_store(duration, key_generator = default_key_generator< Key >{}, clock_function = [] { return clock::now();}); context_store(context_store const &) = delete; context_store & operator=(context_store const &) = delete; duration idle_timeout() const noexcept; std::size_t size() const; entry_ptr find(Key const &); template<typename... Args> entry_ptr emplace(Key, Args &&...); template<typename... Args> std::pair< Key, entry_ptr > create(Args &&...); entry_ptr peek(Key const &) const; std::vector< Key > keys() const; bool erase(Key const &); std::size_t sweep(); awaitable< lock_guard > lock(entry_ptr); };
A context_store holds one Context per Key. Every entry records the time it was last used; entries idle for longer than the store's timeout are removed by sweep, which find, emplace and create run opportunistically, so expired keys behave as unknown without any background timer. Owners that want proactive cleanup (for example to close streams belonging to expired sessions) call sweep themselves on a schedule.
Each entry carries an asynchronous lock. A handler that works on an entry acquires it with lock and holds the returned guard for the duration of the call, so two requests for the same key never run their callables concurrently while requests for different keys run in parallel. Entries that are locked are never swept.
find, emplace and create return shared_ptrs, so a caller that obtained an entry keeps it alive even if it is erased in the meantime.
All members are safe to call from any thread.
typename Key
The lookup key, typically std::string.
typename Context
The user state type held per key.
context_store public member functionsexplicit context_store(duration idle_timeout, key_generator generate = default_key_generator< Key >{}, clock_function now = [] { return clock::now();});Construct a store.
Parameters: |
|
context_store(context_store const &) = delete;
context_store & operator=(context_store const &) = delete;
duration idle_timeout() const noexcept;
std::size_t size() const;Number of entries currently held (including expired, not yet swept).
entry_ptr find(Key const & key);Look up key.
Expired entries are treated as unknown (and removed). A hit refreshes the entry's activity time.
Returns: |
The entry, or an empty pointer. |
template<typename... Args> entry_ptr emplace(Key key, Args &&... args);Create an entry for key, or return the existing one.
args are forwarded to the Context constructor when a new entry is created.
template<typename... Args> std::pair< Key, entry_ptr > create(Args &&... args);Create an entry under a freshly generated key.
entry_ptr peek(Key const & key) const;Look up key without refreshing its activity or sweeping.
For server-initiated work (pushing a notification to a session) that must not keep an otherwise idle entry alive. Expired entries are reported as unknown.
std::vector< Key > keys() const;Keys of all live entries, in no particular order.
bool erase(Key const & key);Remove key. Returns true if an entry was removed.
std::size_t sweep();Remove every idle entry that is not currently locked.
Returns: |
The number of entries removed. |
awaitable< lock_guard > lock(entry_ptr e);Acquire e's lock.
Suspends until no other holder exists, then returns a guard. Hold the guard while using the context; destroy it to release.