diff --git a/include/flock/cxx/group-view.hpp b/include/flock/cxx/group-view.hpp index 07e91d1..44a9c8d 100644 --- a/include/flock/cxx/group-view.hpp +++ b/include/flock/cxx/group-view.hpp @@ -167,6 +167,19 @@ class GroupView { return MetadataProxy{*this}; } + auto copy() const { + auto result = GroupView{}; + auto members = const_cast(this)->members(); + for(size_t i = 0; i < members.count(); ++i) { + result.members().add(members[i].address.c_str(), members[i].provider_id); + } + auto metadata = const_cast(this)->metadata(); + for(size_t i = 0; i < metadata.count(); ++i) { + result.metadata().add(metadata[i].key.c_str(), metadata[i].value.c_str()); + } + return result; + } + operator std::string() const { std::string result; flock_return_t ret = flock_group_view_serialize( diff --git a/python/mochi/flock/client.py b/python/mochi/flock/client.py index c18e682..05170a5 100644 --- a/python/mochi/flock/client.py +++ b/python/mochi/flock/client.py @@ -31,6 +31,7 @@ def client(self): def update(self): self._internal.update() + @property def view(self): return self._internal.view @@ -66,7 +67,7 @@ def make_group_handle(self, address: str|pymargo.core.Address, provider_id: int if isinstance(address, pymargo.core.Address): address = str(address) return GroupHandle( - self._internal.make_service_handle(address=address, provider_id=provider_id), + self._internal.make_group_handle(address=address, provider_id=provider_id), self) def make_group_handle_from_file(self, filename: str): diff --git a/python/mochi/flock/test_group_handle.py b/python/mochi/flock/test_group_handle.py new file mode 100644 index 0000000..d10850c --- /dev/null +++ b/python/mochi/flock/test_group_handle.py @@ -0,0 +1,53 @@ +import unittest +import json +import mochi.flock.client as mfc +import mochi.flock.server as mfs +from mochi.flock.view import GroupView +import pymargo.core + +class TestClient(unittest.TestCase): + + def setUp(self): + self.engine = pymargo.core.Engine("na+sm", pymargo.core.server) + self.address = str(self.engine.address) + config = { + "group": { + "type": "static", + "config": {} + } + } + self.initial_view = GroupView() + for i in range(0, 5): + self.initial_view.members.add(self.address, i) + self.initial_view.metadata.add("mykey", "myvalue") + self.providers = [] + for i in range(0, 5): + self.providers.append( + mfs.Provider(self.engine, i, json.dumps(config), self.initial_view.copy())) + self.client = mfc.Client(self.engine) + + def tearDown(self): + del self.client + del self.providers + self.engine.finalize() + del self.engine + + def test_view(self): + gh = self.client.make_group_handle(self.address, 3) + gh.update() + view = gh.view + self.assertIsInstance(view, GroupView) + self.assertEqual(len(view.members), 5) + for i in range(0, 5): + self.assertEqual(view.members[i].address, self.address) + self.assertEqual(view.members[i].provider_id, i) + self.assertEqual(view.metadata["mykey"], "myvalue") + print(view) + + def test_update(self): + gh = self.client.make_group_handle(self.address, 3) + gh.update() + + +if __name__ == '__main__': + unittest.main() diff --git a/python/src/py-flock-common.cpp b/python/src/py-flock-common.cpp index 8d1b93d..1b3a8a7 100644 --- a/python/src/py-flock-common.cpp +++ b/python/src/py-flock-common.cpp @@ -78,5 +78,6 @@ PYBIND11_MODULE(pyflock_common, m) { .def("__str__", [](const flock::GroupView& gv) { return static_cast(gv); }) + .def("copy", &flock::GroupView::copy) ; } diff --git a/src/provider.c b/src/provider.c index 53e2d04..f9f30c0 100644 --- a/src/provider.c +++ b/src/provider.c @@ -74,7 +74,8 @@ flock_return_t flock_provider_register( .initial_view = FLOCK_GROUP_VIEW_INITIALIZER, .callback_context = NULL, .member_update_callback = dispatch_member_update, - .metadata_update_callback = dispatch_metadata_update + .metadata_update_callback = dispatch_metadata_update, + .join = false }; FLOCK_GROUP_VIEW_MOVE(a.initial_view, &backend_init_args.initial_view); @@ -221,17 +222,17 @@ flock_return_t flock_provider_register( goto finish; // LCOV_EXCL_STOP } - backend_init_args.join = true; bool is_first = false; - for(size_t i = 0; i < backend_init_args.initial_view.members.size; ++i) { - flock_member_t* member = &backend_init_args.initial_view.members.data[i]; - if(member->provider_id != provider_id) continue; - if(strcmp(member->address, self_addr_str) != 0) continue; - backend_init_args.join = false; - is_first = i == 0; - break; + flock_member_t* mem = flock_group_view_find_member( + &backend_init_args.initial_view, self_addr_str, provider_id); + if(mem) { + if(mem == backend_init_args.initial_view.members.data) + is_first = true; + } else { + backend_init_args.join = true; } + /* create the new group's context */ void* context = NULL; ret = a.backend->init_group(&backend_init_args, &context);