diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2021-02-21 22:16:21 +0100 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2021-02-23 22:12:41 +0100 |
commit | c3d6046b25ef0786b8d2919dfa9db4eb05114501 (patch) | |
tree | 19af178d6305c3a83859b7d5b07dbc9b1af3aea5 /src/sync.cpp | |
parent | 52db636c108ab0a16ba0ccf8df55cf28142a230c (diff) |
Sync service
Diffstat (limited to 'src/sync.cpp')
-rw-r--r-- | src/sync.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/sync.cpp b/src/sync.cpp new file mode 100644 index 0000000..37f7ca9 --- /dev/null +++ b/src/sync.cpp @@ -0,0 +1,77 @@ +#include <erebos/sync.h> + +#include <erebos/network.h> + +using namespace erebos; + +using std::scoped_lock; + +static const UUID myUUID("a4f538d0-4e50-4082-8e10-7e3ec2af175d"); + +SyncService::SyncService() = default; +SyncService::~SyncService() = default; + +UUID SyncService::uuid() const +{ + return myUUID; +} + +void SyncService::handle(Context & ctx) +{ + auto pid = ctx.peer().identity(); + if (!pid) + return; + + const auto & powner = pid->finalOwner(); + const auto & owner = ctx.peer().server().identity().finalOwner(); + + if (!powner.sameAs(owner)) + return; + + ctx.local( + ctx.local()->sharedRefAdd(ctx.ref()) + ); +} + +void SyncService::serverStarted(const Server & s) +{ + server = &s; + server->peerList().onUpdate(std::bind(&SyncService::peerWatcher, this, + std::placeholders::_1, std::placeholders::_2)); + watchedHead = server->localHead().watch(std::bind(&SyncService::localStateWatcher, this, + std::placeholders::_1)); +} + +void SyncService::peerWatcher(size_t, const Peer * peer) +{ + if (peer && peer->identity()->finalOwner().sameAs( + server->identity().finalOwner())) { + scoped_lock lock(headMutex); + for (const auto & r : (*watchedHead)->sharedRefs()) + peer->send(myUUID, r); + } +} + +void SyncService::localStateWatcher(const Head<LocalState> & head) +{ + scoped_lock lock(headMutex); + + bool same = head->sharedRefs().size() == + (*watchedHead)->sharedRefs().size(); + if (same) { + for (size_t i = 0; i < head->sharedRefs().size(); i++) + if (head->sharedRefs()[i].digest() != + (*watchedHead)->sharedRefs()[i].digest()) { + same = false; + break; + } + } + + if (!same) { + *watchedHead = head; + const auto & plist = server->peerList(); + for (size_t i = 0; i < plist.size(); i++) + for (const auto & r : (*watchedHead)->sharedRefs()) + plist.at(i).send(myUUID, r); + } +} |