1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #include "rgw/rgw_service.h"
7 #include "rgw/rgw_cache.h"
9 #include "svc_sys_obj_core.h"
13 class RGWSI_SysObj_Cache_CB
;
14 class RGWSI_SysObj_Cache_ASocketHook
;
16 class RGWSI_SysObj_Cache
: public RGWSI_SysObj_Core
18 friend class RGWSI_SysObj_Cache_CB
;
19 friend class RGWServices_Def
;
20 friend class ASocketHandler
;
22 RGWSI_Notify
*notify_svc
{nullptr};
25 std::shared_ptr
<RGWSI_SysObj_Cache_CB
> cb
;
27 void normalize_pool_and_obj(const rgw_pool
& src_pool
, const string
& src_obj
, rgw_pool
& dst_pool
, string
& dst_obj
);
29 void init(RGWSI_RADOS
*_rados_svc
,
30 RGWSI_Zone
*_zone_svc
,
31 RGWSI_Notify
*_notify_svc
) {
32 core_init(_rados_svc
, _zone_svc
);
33 notify_svc
= _notify_svc
;
36 int do_start() override
;
37 void shutdown() override
;
39 int raw_stat(const rgw_raw_obj
& obj
, uint64_t *psize
, real_time
*pmtime
, uint64_t *epoch
,
40 map
<string
, bufferlist
> *attrs
, bufferlist
*first_chunk
,
41 RGWObjVersionTracker
*objv_tracker
,
42 optional_yield y
) override
;
44 int read(RGWSysObjectCtxBase
& obj_ctx
,
45 RGWSI_SysObj_Obj_GetObjState
& read_state
,
46 RGWObjVersionTracker
*objv_tracker
,
47 const rgw_raw_obj
& obj
,
48 bufferlist
*bl
, off_t ofs
, off_t end
,
49 map
<string
, bufferlist
> *attrs
,
51 rgw_cache_entry_info
*cache_info
,
52 boost::optional
<obj_version
>,
53 optional_yield y
) override
;
55 int get_attr(const rgw_raw_obj
& obj
, const char *name
, bufferlist
*dest
,
56 optional_yield y
) override
;
58 int set_attrs(const rgw_raw_obj
& obj
,
59 map
<string
, bufferlist
>& attrs
,
60 map
<string
, bufferlist
> *rmattrs
,
61 RGWObjVersionTracker
*objv_tracker
,
64 int remove(RGWSysObjectCtxBase
& obj_ctx
,
65 RGWObjVersionTracker
*objv_tracker
,
66 const rgw_raw_obj
& obj
,
67 optional_yield y
) override
;
69 int write(const rgw_raw_obj
& obj
,
71 map
<std::string
, bufferlist
>& attrs
,
73 const bufferlist
& data
,
74 RGWObjVersionTracker
*objv_tracker
,
76 optional_yield y
) override
;
78 int write_data(const rgw_raw_obj
& obj
,
81 RGWObjVersionTracker
*objv_tracker
,
84 int distribute_cache(const string
& normal_name
, const rgw_raw_obj
& obj
,
85 ObjectCacheInfo
& obj_info
, int op
,
88 int watch_cb(uint64_t notify_id
,
93 void set_enabled(bool status
);
96 RGWSI_SysObj_Cache(CephContext
*cct
) : RGWSI_SysObj_Core(cct
), asocket(this) {
100 bool chain_cache_entry(std::initializer_list
<rgw_cache_entry_info
*> cache_info_entries
,
101 RGWChainedCache::Entry
*chained_entry
);
102 void register_chained_cache(RGWChainedCache
*cc
);
103 void unregister_chained_cache(RGWChainedCache
*cc
);
105 class ASocketHandler
{
106 RGWSI_SysObj_Cache
*svc
;
108 std::unique_ptr
<RGWSI_SysObj_Cache_ASocketHook
> hook
;
111 ASocketHandler(RGWSI_SysObj_Cache
*_svc
);
117 // `call_list` must iterate over all cache entries and call
118 // `cache_list_dump_helper` with the supplied Formatter on any that
119 // include `filter` as a substring.
121 void call_list(const std::optional
<std::string
>& filter
, Formatter
* f
);
123 // `call_inspect` must look up the requested target and, if found,
124 // dump it to the supplied Formatter and return true. If not found,
125 // it must return false.
127 int call_inspect(const std::string
& target
, Formatter
* f
);
129 // `call_erase` must erase the requested target and return true. If
130 // the requested target does not exist, it should return false.
131 int call_erase(const std::string
& target
);
133 // `call_zap` must erase the cache.
139 class RGWChainedCacheImpl
: public RGWChainedCache
{
140 RGWSI_SysObj_Cache
*svc
{nullptr};
141 ceph::timespan expiry
;
144 std::unordered_map
<std::string
, std::pair
<T
, ceph::coarse_mono_time
>> entries
;
147 RGWChainedCacheImpl() : lock("RGWChainedCacheImpl::lock") {}
148 ~RGWChainedCacheImpl() {
152 svc
->unregister_chained_cache(this);
155 void unregistered() override
{
159 void init(RGWSI_SysObj_Cache
*_svc
) {
164 svc
->register_chained_cache(this);
165 expiry
= std::chrono::seconds(svc
->ctx()->_conf
.get_val
<uint64_t>(
166 "rgw_cache_expiry_interval"));
169 boost::optional
<T
> find(const string
& key
) {
170 std::shared_lock rl
{lock
};
171 auto iter
= entries
.find(key
);
172 if (iter
== entries
.end()) {
175 if (expiry
.count() &&
176 (ceph::coarse_mono_clock::now() - iter
->second
.second
) > expiry
) {
180 return iter
->second
.first
;
183 bool put(RGWSI_SysObj_Cache
*svc
, const string
& key
, T
*entry
,
184 std::initializer_list
<rgw_cache_entry_info
*> cache_info_entries
) {
189 Entry
chain_entry(this, key
, entry
);
191 /* we need the svc cache to call us under its lock to maintain lock ordering */
192 return svc
->chain_cache_entry(cache_info_entries
, &chain_entry
);
195 void chain_cb(const string
& key
, void *data
) override
{
196 T
*entry
= static_cast<T
*>(data
);
197 std::unique_lock wl
{lock
};
198 entries
[key
].first
= *entry
;
199 if (expiry
.count() > 0) {
200 entries
[key
].second
= ceph::coarse_mono_clock::now();
204 void invalidate(const string
& key
) override
{
205 std::unique_lock wl
{lock
};
209 void invalidate_all() override
{
210 std::unique_lock wl
{lock
};
213 }; /* RGWChainedCacheImpl */