Haio
0.2.X
Homebrew Asset IO/CDN
Toggle main menu visibility
Loading...
Searching...
No Matches
cache.cpp
Go to the documentation of this file.
1
#include <
cache/cache.hpp
>
2
3
#include <boost/url/parse.hpp>
4
#include <boost/url/url.hpp>
5
6
#include <stdexcept>
7
8
namespace
asio = boost::asio;
9
namespace
urls = boost::urls;
10
11
namespace
Haio::Cdn
{
12
13
struct
Cache::Impl
{
14
Impl
(asio::any_io_executor executor,
size_t
maxEntriesByIp, std::chrono::seconds window)
15
:
flight
(std::move(executor)),
quota
(maxEntriesByIp, window) {}
16
17
std::unique_ptr<CacheStore>
store
;
18
Detail::SingleFlight
flight
;
19
Detail::ClientQuota
quota
;
20
};
21
22
namespace
{
23
24
/** the scheme of the url picks the backend, the way it picks a bucket's reader */
25
std::unique_ptr<CacheStore> storeFor(
const
CacheConfig
& config, asio::any_io_executor executor) {
26
if
(config.
url
.empty())
return
makeMemoryStore
(config.
maxUsage
, config.
ttl
);
27
28
const
auto
parsed = urls::parse_uri(config.
url
);
29
if
(!parsed)
throw
std::runtime_error(
"cache url is not a url: "
+ config.
url
);
30
31
const
std::string scheme{parsed->scheme()};
32
if
(scheme ==
"file"
) {
33
const
std::string host{parsed->host()};
34
const
std::string path{parsed->path()};
35
if
(host.empty() && (path.empty() || path ==
"/"
)) {
36
throw
std::runtime_error(
"cache url has no directory: "
+ config.
url
);
37
}
38
return
makeFileStore
(std::filesystem::path(host + path), config.
ttl
, config.
maxUsage
);
39
}
40
if
(scheme ==
"redis"
|| scheme ==
"rediss"
) {
41
return
makeRedisStore
(config.
url
, config.
ttl
, config.
maxUsage
, std::move(executor));
42
}
43
// the config already rejected anything else, so reaching here is a bug not a typo
44
throw
std::runtime_error(
"unsupported cache scheme \""
+ scheme +
"\" in "
+ config.
url
);
45
}
46
47
}
48
49
Cache::Cache
(
CacheConfig
config,
size_t
maxEntriesByIp, boost::asio::any_io_executor executor) {
50
impl_ = std::make_shared<Impl>(executor, maxEntriesByIp, config.
ttl
);
51
// a ttl of zero keeps nothing, and still deduplicates
52
if
(config.
ttl
.count() > 0) impl_->store = storeFor(config, std::move(executor));
53
}
54
55
bool
Cache::enabled
()
const
{
56
return
impl_ && impl_->store !=
nullptr
;
57
}
58
59
asio::awaitable<Result<CacheEntry>>
Cache::fetch
(std::string key, std::string client,
Producer
produce) {
60
if
(!impl_)
co_return
co_await
produce();
61
62
if
(impl_->store) {
63
if
(
auto
hit =
co_await
impl_->store->get(key))
co_return
*std::move(hit);
64
}
65
66
// one producer for the key, whether or not what it makes is kept afterwards
67
co_return
co_await
impl_->flight.run(key, [&]() -> asio::awaitable<
Result<CacheEntry>
> {
68
auto
made =
co_await
produce();
69
if
(made && impl_->store && impl_->quota.mayStore(client)) {
70
co_await
impl_->store->put(key, *made);
71
}
72
co_return
made;
73
});
74
}
75
76
}
cache.hpp
Haio::Cdn::Cache::fetch
boost::asio::awaitable< Result< CacheEntry > > fetch(std::string key, std::string client, Producer produce)
Definition
cache.cpp:59
Haio::Cdn::Cache::Producer
std::function< boost::asio::awaitable< Result< CacheEntry > >()> Producer
Definition
haio_cache.hpp:79
Haio::Cdn::Cache::enabled
bool enabled() const
Definition
cache.cpp:55
Haio::Cdn::Cache::Cache
Cache()=default
Haio::Cdn::Detail::ClientQuota
Definition
cache.hpp:44
Haio::Cdn::Detail::SingleFlight
Definition
cache.hpp:23
Haio::Cdn
Definition
haio_cache.hpp:16
Haio::Cdn::makeMemoryStore
std::unique_ptr< CacheStore > makeMemoryStore(size_t maxUsage, std::chrono::seconds ttl)
Definition
memory.cpp:87
Haio::Cdn::makeRedisStore
std::unique_ptr< CacheStore > makeRedisStore(std::string url, std::chrono::seconds ttl, size_t maxUsage, boost::asio::any_io_executor executor)
Haio::Cdn::CacheConfig::maxUsage
size_t maxUsage
Definition
haio_cache.hpp:30
Haio::Cdn::makeFileStore
std::unique_ptr< CacheStore > makeFileStore(std::filesystem::path root, std::chrono::seconds ttl, size_t maxUsage)
Definition
file.cpp:171
Haio::Cdn::CacheConfig::ttl
std::chrono::seconds ttl
Definition
haio_cache.hpp:29
Haio::Cdn::CacheConfig::url
std::string url
Definition
haio_cache.hpp:31
Haio::Cdn::CacheConfig
Definition
haio_cache.hpp:28
Haio::Result
std::expected< T, Error > Result
Definition
haio_codec.hpp:32
Haio::Cdn::Cache::Impl
Definition
cache.cpp:13
Haio::Cdn::Cache::Impl::quota
Detail::ClientQuota quota
Definition
cache.cpp:19
Haio::Cdn::Cache::Impl::store
std::unique_ptr< CacheStore > store
Definition
cache.cpp:17
Haio::Cdn::Cache::Impl::Impl
Impl(asio::any_io_executor executor, size_t maxEntriesByIp, std::chrono::seconds window)
Definition
cache.cpp:14
Haio::Cdn::Cache::Impl::flight
Detail::SingleFlight flight
Definition
cache.cpp:18
library
frontend
cdn
cache
cache.cpp
Generated by
1.18.0