mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 04:21:51 +00:00
op_cache, proxy_client: honor GetCallback return and guard push refresh expiry
- SearchCache::get: if gcb returns false, call dcb(false, {}) instead
of silently proceeding with dcb(true, {}).
- DhtProxyClient push refresh: skip expiration of old values when the
get() completion reports failure (ok == false), preventing spurious
expires on transient errors.
In pushNotificationReceived, track the set of value IDs received
in the refresh GET and only expire values whose IDs are not in the
new set. Previously all old values were expired on refresh,
incorrectly expiring edited values.
This commit is contained in:
1 parent
3627090257
commit
8a8b4d41ca
2 files changed
+24
-10
No files matched your search
@@ -1310,13 +1310,25 @@ DhtProxyClient::pushNotificationReceived([[maybe_unused]] const std::map<std::st
|
||||
if (expired == notification.end()) {
|
||||
auto cb = list.second.cb;
|
||||
auto oldValues = list.second.cache.getValues();
|
||||
auto receivedIds = std::make_shared<std::set<Value::Id>>();
|
||||
get(
|
||||
key,
|
||||
[cb, sendTime](const std::vector<Sp<Value>>& vals) { return cb(vals, false, sendTime); },
|
||||
[cb, oldValues, sendTime](bool /*ok*/) {
|
||||
[cb, sendTime, receivedIds](const std::vector<Sp<Value>>& vals) {
|
||||
for (const auto& v : vals)
|
||||
receivedIds->insert(v->id);
|
||||
return cb(vals, false, sendTime);
|
||||
},
|
||||
[cb, oldValues, sendTime, receivedIds](bool ok) {
|
||||
if (!ok)
|
||||
return;
|
||||
// Decrement old values refcount to expire values not
|
||||
// present in the new list
|
||||
cb(oldValues, true, sendTime);
|
||||
std::vector<Sp<Value>> toExpire;
|
||||
for (const auto& v : oldValues)
|
||||
if (receivedIds->find(v->id) == receivedIds->end())
|
||||
toExpire.emplace_back(v);
|
||||
if (!toExpire.empty())
|
||||
cb(toExpire, true, sendTime);
|
||||
});
|
||||
ret = PushNotificationResult::Values;
|
||||
} else {
|
||||
|
||||
+9
-7
@@ -244,15 +244,17 @@ SearchCache::expire(const time_point& now, const std::function<void(size_t)>& on
|
||||
bool
|
||||
SearchCache::get(const Value::Filter& f, const Sp<Query>& q, const GetCallback& gcb, const DoneCallback& dcb) const
|
||||
{
|
||||
if (not gcb)
|
||||
return false;
|
||||
auto op = getOp(q);
|
||||
if (op != ops.end() and op->second->isSynced()) {
|
||||
auto vals = op->second->get(f);
|
||||
if (not vals.empty())
|
||||
gcb(vals);
|
||||
if (op == ops.end() or not op->second->isSynced())
|
||||
return false;
|
||||
auto vals = op->second->get(f);
|
||||
if (not vals.empty())
|
||||
gcb(vals); // a consumer stopping early is not a failure
|
||||
if (dcb)
|
||||
dcb(true, {});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Sp<Value>>
|
||||
|
||||
Reference in new issue
Block a user