mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 20:37:23 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
134b37861d | ||
|
|
078e0a0c3e | ||
|
|
c4857bf595 |
No files matched your search
+1
-1
@@ -93,7 +93,7 @@ Dht::shutdown(ShutdownCallback cb, bool stop)
|
||||
r.second.done_cb(false, {});
|
||||
sr.second->callbacks.clear();
|
||||
for (const auto& a : sr.second->announce) {
|
||||
if (a.callback) a.callback(false, {});
|
||||
for (auto& cb : a.callbacks) cb(false, {});
|
||||
}
|
||||
sr.second->announce.clear();
|
||||
sr.second->listeners.clear();
|
||||
|
||||
@@ -1121,10 +1121,12 @@ DhtProxyClient::sendListen(const restinio::http_request_header_t& header,
|
||||
std::lock_guard<std::mutex> l(requestLock_);
|
||||
requests_[reqid] = request;
|
||||
}
|
||||
request->add_on_status_callback([request, seconds = this->listenKeepIdle()] (unsigned status_code) {
|
||||
request->add_on_status_callback([r=std::weak_ptr(request), seconds = this->listenKeepIdle()] (unsigned status_code) {
|
||||
if(status_code == 200) {
|
||||
// increase TCP_KEEPIDLE to save power
|
||||
request->get_connection()->set_keepalive(seconds);
|
||||
if (auto request = r.lock()) {
|
||||
request->get_connection()->set_keepalive(seconds);
|
||||
}
|
||||
}
|
||||
});
|
||||
request->send();
|
||||
|
||||
+26
-19
@@ -45,7 +45,7 @@ struct Dht::Announce {
|
||||
bool permanent;
|
||||
Sp<Value> value;
|
||||
time_point created;
|
||||
DoneCallback callback;
|
||||
std::vector<DoneCallback> callbacks;
|
||||
};
|
||||
|
||||
struct Dht::SearchNode {
|
||||
@@ -442,8 +442,9 @@ struct Dht::Search {
|
||||
g.second.done_cb = {};
|
||||
}
|
||||
for (auto& a : announce) {
|
||||
a.callback(false, {});
|
||||
a.callback = {};
|
||||
for (auto& cb : a.callbacks)
|
||||
cb(false, {});
|
||||
a.callbacks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,7 +628,9 @@ struct Dht::Search {
|
||||
return a.value->id == value->id;
|
||||
});
|
||||
if (a_sr == announce.end()) {
|
||||
announce.emplace_back(Announce {permanent, value, created, callback});
|
||||
auto& a = announce.emplace_back(Announce {permanent, value, created, {}} );
|
||||
if (callback)
|
||||
a.callbacks.emplace_back(std::move(callback));
|
||||
for (auto& n : nodes) {
|
||||
n->probe_query.reset();
|
||||
n->acked[value->id].req.reset();
|
||||
@@ -635,24 +638,26 @@ struct Dht::Search {
|
||||
} else {
|
||||
a_sr->permanent = permanent;
|
||||
a_sr->created = created;
|
||||
if (a_sr->value != value) {
|
||||
if (a_sr->value != value && *a_sr->value != *value) {
|
||||
// Value is updated, previous ops are failed
|
||||
a_sr->value = value;
|
||||
for (auto& n : nodes) {
|
||||
n->acked[value->id].req.reset();
|
||||
n->probe_query.reset();
|
||||
}
|
||||
}
|
||||
if (isAnnounced(value->id)) {
|
||||
if (a_sr->callback)
|
||||
a_sr->callback(true, {});
|
||||
a_sr->callback = {};
|
||||
for (auto& cb: a_sr->callbacks)
|
||||
cb(false, {});
|
||||
a_sr->callbacks.clear();
|
||||
if (callback)
|
||||
a_sr->callbacks.emplace_back(std::move(callback));
|
||||
} else if (isAnnounced(value->id)) {
|
||||
// Same value, already announced
|
||||
if (callback)
|
||||
callback(true, {});
|
||||
return;
|
||||
} else {
|
||||
if (a_sr->callback)
|
||||
a_sr->callback(false, {});
|
||||
a_sr->callback = callback;
|
||||
// Same value, not announced yet
|
||||
if (callback)
|
||||
a_sr->callbacks.emplace_back(std::move(callback));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -722,8 +727,8 @@ struct Dht::Search {
|
||||
std::vector<DoneCallback> a_cbs;
|
||||
a_cbs.reserve(announce.size());
|
||||
for (auto ait = announce.begin() ; ait != announce.end(); ) {
|
||||
if (ait->callback)
|
||||
a_cbs.emplace_back(std::move(ait->callback));
|
||||
a_cbs.insert(a_cbs.end(), std::make_move_iterator(ait->callbacks.begin()), std::make_move_iterator(ait->callbacks.end()));
|
||||
ait->callbacks.clear();
|
||||
if (not ait->permanent)
|
||||
ait = announce.erase(ait);
|
||||
else
|
||||
@@ -747,9 +752,11 @@ struct Dht::Search {
|
||||
if (vid != Value::INVALID_ID and (!a.value || a.value->id != vid))
|
||||
return true;
|
||||
if (isAnnounced(a.value->id)) {
|
||||
if (a.callback) {
|
||||
a.callback(true, getNodes());
|
||||
a.callback = nullptr;
|
||||
if (!a.callbacks.empty()) {
|
||||
const auto& nodes = getNodes();
|
||||
for (auto& cb : a.callbacks)
|
||||
cb(true, nodes);
|
||||
a.callbacks.clear();
|
||||
}
|
||||
if (not a.permanent)
|
||||
return false;
|
||||
|
||||
@@ -90,6 +90,59 @@ DhtRunnerTester::testGetPut() {
|
||||
CPPUNIT_ASSERT(vals.front()->data == val_data);
|
||||
}
|
||||
|
||||
void
|
||||
DhtRunnerTester::testPutDuplicate() {
|
||||
auto key = dht::InfoHash::get("123");
|
||||
auto val = std::make_shared<dht::Value>("hey");
|
||||
val->id = 42;
|
||||
auto val_data = val->data;
|
||||
std::promise<bool> p1;
|
||||
std::promise<bool> p2;
|
||||
node2.put(key, val, [&](bool ok){
|
||||
p1.set_value(ok);
|
||||
});
|
||||
node2.put(key, val, [&](bool ok){
|
||||
p2.set_value(ok);
|
||||
});
|
||||
auto p1ret = p1.get_future().get();
|
||||
auto p2ret = p2.get_future().get();
|
||||
CPPUNIT_ASSERT(p1ret);
|
||||
CPPUNIT_ASSERT(p2ret);
|
||||
auto vals = node1.get(key).get();
|
||||
CPPUNIT_ASSERT(not vals.empty());
|
||||
CPPUNIT_ASSERT(vals.size() == 1);
|
||||
CPPUNIT_ASSERT(vals.front()->data == val_data);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DhtRunnerTester::testPutOverride() {
|
||||
auto key = dht::InfoHash::get("123");
|
||||
auto val = std::make_shared<dht::Value>("meh");
|
||||
val->id = 42;
|
||||
auto val2 = std::make_shared<dht::Value>("hey");
|
||||
val2->id = 42;
|
||||
CPPUNIT_ASSERT_EQUAL(val->id, val2->id);
|
||||
auto val_data = val->data;
|
||||
std::promise<bool> p1;
|
||||
std::promise<bool> p2;
|
||||
node2.put(key, val, [&](bool ok){
|
||||
p1.set_value(ok);
|
||||
});
|
||||
node2.put(key, val2, [&](bool ok){
|
||||
p2.set_value(ok);
|
||||
});
|
||||
auto p1ret = p1.get_future().get();
|
||||
auto p2ret = p2.get_future().get();
|
||||
CPPUNIT_ASSERT(!p1ret);
|
||||
CPPUNIT_ASSERT(p2ret);
|
||||
auto vals = node1.get(key).get();
|
||||
CPPUNIT_ASSERT(not vals.empty());
|
||||
CPPUNIT_ASSERT(vals.size() == 1);
|
||||
CPPUNIT_ASSERT(vals.front()->data == val_data);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DhtRunnerTester::testListen() {
|
||||
std::mutex mutex;
|
||||
|
||||
@@ -31,6 +31,7 @@ class DhtRunnerTester : public CppUnit::TestFixture {
|
||||
CPPUNIT_TEST_SUITE(DhtRunnerTester);
|
||||
CPPUNIT_TEST(testConstructors);
|
||||
CPPUNIT_TEST(testGetPut);
|
||||
CPPUNIT_TEST(testPutDuplicate);
|
||||
CPPUNIT_TEST(testListen);
|
||||
CPPUNIT_TEST(testListenLotOfBytes);
|
||||
CPPUNIT_TEST(testIdOps);
|
||||
@@ -55,6 +56,14 @@ class DhtRunnerTester : public CppUnit::TestFixture {
|
||||
* Test get and put methods
|
||||
*/
|
||||
void testGetPut();
|
||||
/**
|
||||
* Test get and multiple put
|
||||
*/
|
||||
void testPutDuplicate();
|
||||
/**
|
||||
* Test get and multiple put with changing value
|
||||
*/
|
||||
void testPutOverride();
|
||||
/**
|
||||
* Test listen method
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user