From 45a5d2d07bb1956edde412d20f8fa7ff02a86e77 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 18 Sep 2024 17:45:00 +0200 Subject: [PATCH] ApiListener::UpdateObjectAuthority(): distribute auth. by object's host Pin child objects of hosts (HOST!...) to the same endpoint as the host. This reduces cross-object action latency withing the same host. If all endpoints know this algorithm, we can use it. --- lib/remote/apilistener-authority.cpp | 27 ++++++++++++++++++++++++--- lib/remote/apilistener.cpp | 4 +++- lib/remote/apilistener.hpp | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/remote/apilistener-authority.cpp b/lib/remote/apilistener-authority.cpp index f33a1905bf1..35f7a997928 100644 --- a/lib/remote/apilistener-authority.cpp +++ b/lib/remote/apilistener-authority.cpp @@ -25,6 +25,7 @@ void ApiListener::UpdateObjectAuthority() std::vector endpoints; Endpoint::Ptr my_endpoint; + int hostChildrenInheritObjectAuthority = 0; if (my_zone) { my_endpoint = Endpoint::GetLocalEndpoint(); @@ -51,6 +52,12 @@ void ApiListener::UpdateObjectAuthority() return a->GetName() < b->GetName(); } ); + + for (auto& endpoint : endpoints) { + if (endpoint == my_endpoint || endpoint->GetCapabilities() & (uint_fast64_t)ApiCapabilities::HostChildrenInheritObjectAuthority) { + ++hostChildrenInheritObjectAuthority; + } + } } for (const Type::Ptr& type : Type::GetAllTypes()) { @@ -65,10 +72,24 @@ void ApiListener::UpdateObjectAuthority() bool authority; - if (!my_zone) + if (my_zone) { + auto name (object->GetName()); + + // If all endpoints know this algorithm, we can use it. + if (hostChildrenInheritObjectAuthority == endpoints.size()) { + auto exclamation (name.FindFirstOf('!')); + + // Pin child objects of hosts (HOST!...) to the same endpoint as the host. + // This reduces cross-object action latency withing the same host. + if (exclamation != String::NPos) { + name = name.SubStr(0, exclamation); + } + } + + authority = endpoints[Utility::SDBM(name) % endpoints.size()] == my_endpoint; + } else { authority = true; - else - authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint; + } #ifdef I2_DEBUG // //Enable on demand, causes heavy logging on each run. diff --git a/lib/remote/apilistener.cpp b/lib/remote/apilistener.cpp index f740fe13baf..0c6835cc154 100644 --- a/lib/remote/apilistener.cpp +++ b/lib/remote/apilistener.cpp @@ -644,7 +644,9 @@ static const auto l_AppVersionInt (([]() -> unsigned long { })()); static const auto l_MyCapabilities ( - (uint_fast64_t)ApiCapabilities::ExecuteArbitraryCommand | (uint_fast64_t)ApiCapabilities::IfwApiCheckCommand + (uint_fast64_t)ApiCapabilities::ExecuteArbitraryCommand + | (uint_fast64_t)ApiCapabilities::IfwApiCheckCommand + | (uint_fast64_t)ApiCapabilities::HostChildrenInheritObjectAuthority ); /** diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index fced0a8afb1..9a54d374b39 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -69,6 +69,7 @@ enum class ApiCapabilities : uint_fast64_t { ExecuteArbitraryCommand = 1u << 0u, IfwApiCheckCommand = 1u << 1u, + HostChildrenInheritObjectAuthority = 1u << 2u, }; /**