*/
OPTION(rgw_bucket_index_max_aio, OPT_U32, 8)
+/**
+ * Number of seconds before entries in the bucket info cache are
+ * assumed stale and re-fetched. Zero is never.
+ */
+OPTION(rgw_cache_expiry_interval, OPT_U64, 900 /* 15 min */)
+
/**
* whether or not the quota/gc threads should be started
*/
template <class T>
class RGWChainedCacheImpl : public RGWChainedCache {
+ ceph::timespan expiry;
RWLock lock;
- map<string, T> entries;
+ map<string, std::pair<T, ceph::coarse_mono_time>> entries;
public:
RGWChainedCacheImpl() : lock("RGWChainedCacheImpl::lock") {}
void init(RGWRados *store) {
store->register_chained_cache(this);
+ expiry = std::chrono::seconds(store->ctx()->_conf->rgw_cache_expiry_interval);
}
bool find(const string& key, T *entry) {
RWLock::RLocker rl(lock);
- typename map<string, T>::iterator iter = entries.find(key);
+ auto iter = entries.find(key);
if (iter == entries.end()) {
return false;
}
+ if (expiry.count() &&
+ (ceph::coarse_mono_clock::now() - iter->second.second) > expiry) {
+ return false;
+ }
- *entry = iter->second;
+ *entry = iter->second.first;
return true;
}
void chain_cb(const string& key, void *data) {
T *entry = static_cast<T *>(data);
RWLock::WLocker wl(lock);
- entries[key] = *entry;
+ entries[key].first = *entry;
+ if (expiry.count() > 0) {
+ entries[key].second = ceph::coarse_mono_clock::now();
+ }
}
void invalidate(const string& key) {