From a13474cd11283ae648e0dcaa156ce9058df15aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Wed, 22 Feb 2023 20:58:39 +0100 Subject: Pass weak pointer of HeadBhv to callback --- include/erebos/storage.h | 31 +++++++++++++++++++++++------ test/storage.test | 51 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/include/erebos/storage.h b/include/erebos/storage.h index 01aeada..c506dfd 100644 --- a/include/erebos/storage.h +++ b/include/erebos/storage.h @@ -528,6 +528,7 @@ void filterAncestors(std::vector> & xs) } template class WatchedHead; +template class HeadBhv; template class Head @@ -562,8 +563,13 @@ template class WatchedHead : public Head { friend class Head; + friend class HeadBhv; + + WatchedHead(const Head & h): + Head(h), watcherId(-1) {} WatchedHead(const Head & h, int watcherId): Head(h), watcherId(watcherId) {} + int watcherId; public: @@ -588,15 +594,26 @@ class HeadBhv : public BhvSource { public: HeadBhv(const Head & head): - whead(head.watch([this] (const Head & cur) { - BhvCurTime ctime; - whead = cur; - BhvImplBase::updated(ctime); - })) {} + whead(head) + {} T get(const BhvCurTime &, const std::monostate &) const { return *whead; } private: + friend class Head; + + void init() + { + whead = whead.watch([wp = weak_ptr(BhvImplBase::shared_from_this()), this] (const Head & cur) { + // make sure this object still exists + if (auto ptr = wp.lock()) { + BhvCurTime ctime; + whead = cur; + BhvImplBase::updated(ctime); + } + }); + } + WatchedHead whead; }; @@ -665,7 +682,9 @@ template Bhv Head::behavior() const { auto cur = reload(); - return make_shared>(cur ? *cur : *this); + auto ret = make_shared>(cur ? *cur : *this); + ret->init(); + return ret; } template diff --git a/test/storage.test b/test/storage.test index 17859cc..6267beb 100644 --- a/test/storage.test +++ b/test/storage.test @@ -1,4 +1,4 @@ -test: +test Storage: spawn as p1 # Root finding @@ -150,3 +150,52 @@ test: /stored-set-item $r2_3/ /stored-set-(.*)/ capture done6 guard done6 == "done" + + +test StorageWatcher: + spawn as p1 + spawn as p2 + send "create-identity Device1 Owner" to p1 + send "create-identity Device2" to p2 + send "watch-local-identity" to p1 + send "watch-local-identity" to p2 + send "start-server" to p1 + send "start-server" to p2 + expect from p1: + /local-identity Device1 Owner/ + /peer 1 addr ${p2.node.ip} 29665/ + /peer 1 id Device2/ + expect from p2: + /local-identity Device2/ + /peer 1 addr ${p1.node.ip} 29665/ + /peer 1 id Device1 Owner/ + + local: + send "attach-to 1" to p2 + expect /attach-request 1 ([0-9]*)/ from p1 capture code1 + expect /attach-response 1 ([0-9]*)/ from p2 capture code2 + guard code1 == code2 + + send "attach-accept 1" to p1 + send "attach-accept 1" to p2 + expect /attach-request-done 1/ from p1 + expect /attach-response-done 1/ from p2 + expect /local-identity Device2 Owner/ from p2 + expect /peer 1 id Device2 Owner/ from p1 + + for i in [1..5]: + send "update-local-identity Owner2" to p1 + send "shared-state-get" to p1 + expect /shared-state-get (.*)/ from p1 capture s1 + + send "shared-state-wait $s1" to p2 + expect /shared-state-wait $s1/ from p2 + + send "update-local-identity Owner1" to p1 + send "shared-state-get" to p1 + expect /shared-state-get (.*)/ from p1 capture s2 + + send "shared-state-wait $s1" to p2 + send "shared-state-wait $s2" to p2 + expect /shared-state-wait $s1/ from p2 + expect /shared-state-wait $s2/ from p2 -- cgit v1.2.3