6 #include <unordered_map> 34 std::chrono::time_point<ClockType>
expires;
35 std::future<std::string>
fut;
39 std::unordered_map<IndexType, Element>
elems;
41 std::chrono::seconds default_expire = 120s;
42 constexpr
static std::chrono::seconds init_expire = std::chrono::seconds::max();
52 template <
class Fcn> std::optional<IndexType>
launch(Fcn&& fcn, std::optional<std::chrono::seconds> expire_opt = std::nullopt) {
53 static_assert(std::is_same_v<std::invoke_result_t<Fcn>, std::string>);
54 if (elems.size() == std::numeric_limits<IndexType>::max())
57 std::lock_guard guard{mut};
58 const auto id = last_id = get_free_id();
59 auto [it, sucess] = elems.emplace(
id, std::move(
Element{std::chrono::time_point<ClockType>{init_expire}, {}}));
61 it->second.fut = std::async(std::launch::async, [&, expire_opt,
id, fcn = std::forward<Fcn>(fcn)]() -> std::string {
62 std::string ret = fcn();
65 std::lock_guard guard{mut};
66 auto& [exp, fut ] = elems[id];
67 exp = ClockType::now() + expire_opt.value_or(default_expire);
84 std::lock_guard guard{mut};
85 const auto it = elems.find(
id);
86 if (it == elems.end())
87 return {TaskStatus::non_existent, {}};
89 auto& [expires, fut] = it->second;
91 if (future_status(fut) != std::future_status::ready)
92 return {TaskStatus::in_progress, {}};
94 auto node = elems.extract(it);
95 return {TaskStatus::finished, fut.get()};
103 for (
auto it = elems.begin(), last = elems.end(); it != last;) {
104 if (
auto& [key, val] = *it; val.expires > ClockType::now() && future_status(val.fut) == std::future_status::ready) {
105 it = elems.erase(it);
119 template <
class T>
static std::future_status future_status(
const std::future<T>& fut) {
return fut.wait_for(std::chrono::seconds{0}); }
128 while (elems.count(++
id) > 0)
std::pair< TaskStatus, std::string > value_if_ready(IndexType id)
Definition: async_store.hpp:83
std::chrono::system_clock ClockType
Type used for the expiration clock.
Definition: async_store.hpp:17
Definition: async_store.hpp:33
std::chrono::time_point< ClockType > expires
point of expiry of the store entry
Definition: async_store.hpp:34
std::unordered_map< IndexType, Element > elems
actual container of entries
Definition: async_store.hpp:39
TaskStatus
Definition: async_store.hpp:23
std::uint32_t IndexType
Type used as the key to elems.
Definition: async_store.hpp:16
void gc() noexcept
Definition: async_store.hpp:102
Definition: async_store.hpp:15
std::optional< IndexType > launch(Fcn &&fcn, std::optional< std::chrono::seconds > expire_opt=std::nullopt)
Definition: async_store.hpp:52
std::future< std::string > fut
promise of the response body
Definition: async_store.hpp:35