diff --git a/SilKit/IntegrationTests/ITest_Internals_DataPubSub.cpp b/SilKit/IntegrationTests/ITest_Internals_DataPubSub.cpp index 641838918..16408053e 100644 --- a/SilKit/IntegrationTests/ITest_Internals_DataPubSub.cpp +++ b/SilKit/IntegrationTests/ITest_Internals_DataPubSub.cpp @@ -805,4 +805,83 @@ TEST_F(ITest_Internals_DataPubSub, test_1pub_1sub_async_rejoin) ShutdownSystem(); } + +// Two publishers (optional label1), one subscriber (optional label1, label2); publishers start first; subscriber joins +TEST_F(ITest_Internals_DataPubSub, test_2pub_1sub_async_starting_order) +{ + const uint32_t numMsgToPublish = 1; + const uint32_t numMsgToReceive = 1 * numMsgToPublish; + + std::vector publishers; + publishers.push_back({"Pub1", + {{"PubCtrl1", + "TopicA", + {"A"}, + {{"K1", "V1", SilKit::Services::MatchingLabel::Kind::Optional}}, + 1, + defaultMsgSize, + numMsgToPublish}}, + {}}); + publishers.push_back({"Pub2", + {{"PubCtrl1", + "TopicA", + {"A"}, + {{"K1", "V1", SilKit::Services::MatchingLabel::Kind::Optional}}, + 1, + defaultMsgSize, + numMsgToPublish}}, + {}}); + + std::vector subscribers; + std::vector> expectedDataUnordered; + expectedDataUnordered.reserve(numMsgToReceive); + for (uint32_t d = 0; d < numMsgToReceive; d++) + { + // Receive the same blob several times (once from every publisher) + expectedDataUnordered.emplace_back(std::vector(defaultMsgSize, 0)); + } + subscribers.push_back( + {"Sub1", + {}, + {{ + "SubCtrl1", + "TopicA", + {"A"}, + {{"K1", "V1", SilKit::Services::MatchingLabel::Kind::Optional}, + {"K2", "V2", SilKit::Services::MatchingLabel::Kind::Optional} + }, // BUGHUNT: Second label breaks communication + defaultMsgSize, + numMsgToReceive, + 1, + expectedDataUnordered, + }}}); + + for (auto& sub : subscribers) + { + sub.communicationTimeout = std::chrono::milliseconds(1000); + } + + _testSystem.SetupRegistryAndSystemMaster("silkit://localhost:0", false, {}); + + + //BUGHUNT: Subscribers start first fails SOMETIMES + //RunParticipants(subscribers, _testSystem.GetRegistryUri(), false); + + //BUGHUNT: Publishers start first fails ALWAYS + + // Start publishers + RunParticipants(publishers, _testSystem.GetRegistryUri(), false); + for (auto& p : publishers) + { + p.WaitForAllSent(); + } + + // Start subscriber + RunParticipants(subscribers, _testSystem.GetRegistryUri(), false); + + + JoinPubSubThreads(); + ShutdownSystem(); +} + } // anonymous namespace diff --git a/SilKit/IntegrationTests/ITest_Internals_DataPubSub.hpp b/SilKit/IntegrationTests/ITest_Internals_DataPubSub.hpp index 107cc9efe..1ff4f15ee 100644 --- a/SilKit/IntegrationTests/ITest_Internals_DataPubSub.hpp +++ b/SilKit/IntegrationTests/ITest_Internals_DataPubSub.hpp @@ -178,6 +178,7 @@ class ITest_Internals_DataPubSub : public testing::Test , name{newName} , dataSubscribers{newDataSubscribers} , dataPublishers{newDataPublishers} + , allReceived{std::make_unique>(false)} { } @@ -186,6 +187,7 @@ class ITest_Internals_DataPubSub : public testing::Test std::string name; std::vector dataSubscribers; std::vector dataPublishers; + std::unique_ptr> allReceived; std::unique_ptr participant; SilKit::Core::IParticipantInternal* participantImpl = nullptr; @@ -196,7 +198,6 @@ class ITest_Internals_DataPubSub : public testing::Test std::promise allDiscoveredPromise; bool allDiscovered{false}; std::promise allReceivedPromise; - bool allReceived{false}; // Pub std::promise allSentPromise; bool allSent{false}; @@ -208,7 +209,7 @@ class ITest_Internals_DataPubSub : public testing::Test if (std::all_of(dataSubscribers.begin(), dataSubscribers.end(), [](const auto& dsInfo) { return dsInfo.numMsgToReceive == 0; })) { - allReceived = true; + *allReceived = true; allReceivedPromise.set_value(); } } @@ -224,11 +225,11 @@ class ITest_Internals_DataPubSub : public testing::Test void CheckAllReceivedPromise() { - if (!allReceived && std::all_of(dataSubscribers.begin(), dataSubscribers.end(), [](const auto& dsInfo) { + if (!*allReceived && std::all_of(dataSubscribers.begin(), dataSubscribers.end(), [](const auto& dsInfo) { return dsInfo.allReceived; })) { - allReceived = true; + *allReceived = true; allReceivedPromise.set_value(); } } diff --git a/SilKit/IntegrationTests/IntegrationTestInfrastructure.hpp b/SilKit/IntegrationTests/IntegrationTestInfrastructure.hpp index d38f77ae2..1a2d12135 100644 --- a/SilKit/IntegrationTests/IntegrationTestInfrastructure.hpp +++ b/SilKit/IntegrationTests/IntegrationTestInfrastructure.hpp @@ -25,7 +25,10 @@ class TestInfrastructure { std::stringstream ss; ss << "Something went wrong: " << error.what() << std::endl; - _systemMaster.systemController->AbortSimulation(); + if (_systemMaster.systemController) + { + _systemMaster.systemController->AbortSimulation(); + } FAIL() << ss.str(); } @@ -127,7 +130,7 @@ class TestInfrastructure struct SystemMaster { std::unique_ptr participant; - SilKit::Experimental::Services::Orchestration::ISystemController* systemController; + SilKit::Experimental::Services::Orchestration::ISystemController* systemController{nullptr}; ISystemMonitor* systemMonitor; ILifecycleService* lifecycleService; diff --git a/SilKit/include/silkit/services/datatypes.hpp b/SilKit/include/silkit/services/datatypes.hpp index ec127decb..366bcb323 100644 --- a/SilKit/include/silkit/services/datatypes.hpp +++ b/SilKit/include/silkit/services/datatypes.hpp @@ -6,6 +6,7 @@ #include #include +#include #include "silkit/util/HandlerId.hpp" @@ -44,6 +45,11 @@ struct MatchingLabel std::string key; //!< The label's key. std::string value; //!< The label's key. Kind kind; //!< The matching kind to apply for this label. + + friend bool operator==(const MatchingLabel& lhs, const MatchingLabel& rhs) noexcept + { + return std::tie(lhs.key, lhs.value, lhs.kind) == std::tie(rhs.key, rhs.value, rhs.kind); + } }; using SilKit::Util::HandlerId; diff --git a/SilKit/source/core/internal/ServiceDescriptor.hpp b/SilKit/source/core/internal/ServiceDescriptor.hpp index 6b7105227..d92a001e0 100644 --- a/SilKit/source/core/internal/ServiceDescriptor.hpp +++ b/SilKit/source/core/internal/ServiceDescriptor.hpp @@ -85,6 +85,7 @@ class ServiceDescriptor inline bool GetSupplementalDataItem(const std::string& key, std::string& value) const; inline void SetSupplementalDataItem(std::string key, std::string val); + inline std::string getVal(const std::string& key) const; inline auto GetSimulationName() const -> const std::string&; inline void SetSimulationName(const std::string& simulationName); @@ -137,6 +138,17 @@ void ServiceDescriptor::SetSupplementalDataItem(std::string key, std::string val _supplementalData[key] = std::move(val); } +std::string ServiceDescriptor::getVal(const std::string& key) const +{ + std::string tmp; + if(GetSupplementalDataItem(key, tmp) == false) + { + throw SilKit::StateError{"Unknown key in supplementalData"}; + } + + return tmp; +} + auto ServiceDescriptor::GetParticipantId() const -> ParticipantId { return _participantId; diff --git a/SilKit/source/core/service/SpecificDiscoveryStore.cpp b/SilKit/source/core/service/SpecificDiscoveryStore.cpp index ed7a76bcd..c5111c908 100644 --- a/SilKit/source/core/service/SpecificDiscoveryStore.cpp +++ b/SilKit/source/core/service/SpecificDiscoveryStore.cpp @@ -3,7 +3,9 @@ // SPDX-License-Identifier: MIT #include "SpecificDiscoveryStore.hpp" +#include "LabelMatching.hpp" #include "YamlParser.hpp" + namespace { inline auto MakeFilter(const std::string& type, const std::string& topicOrFunction) -> SilKit::Core::Discovery::FilterType @@ -77,7 +79,7 @@ void SpecificDiscoveryStore::CallHandlerOnHandlerRegistration( const ServiceDiscoveryHandler& handler, const std::string& controllerType_, const std::string& key, const std::vector& labels) { - // pre filter key and mediaType + // pre filter controllerType and Topic/Function auto& entry = _lookup[MakeFilter(controllerType_, key)]; auto* greedyLabel = GetLabelWithMinimalNodeSet(entry, labels); @@ -87,27 +89,45 @@ void SpecificDiscoveryStore::CallHandlerOnHandlerRegistration( // no labels present trigger all for (auto&& serviceDescriptor : entry.allCluster.nodes) { - handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + const auto descriptorLabels = GetLabels(serviceDescriptor); + if(Util::MatchLabels(labels, descriptorLabels)) + { + handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + } } } else { + if (greedyLabel->kind == SilKit::Services::MatchingLabel::Kind::Optional) { - // trigger notlabel handlers + // Get all services that do not have the same optional label present for (auto&& serviceDescriptor : entry.notLabelMap[greedyLabel->key].nodes) { - handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + const auto descriptorLabels = GetLabels(serviceDescriptor); + if(Util::MatchLabels(labels, descriptorLabels)) + { + handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + } } + // Get all services that do not have any labels attached, thus matching our optional label for (auto&& serviceDescriptor : entry.noLabelCluster.nodes) { - handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + const auto descriptorLabels = GetLabels(serviceDescriptor); + if(Util::MatchLabels(labels, descriptorLabels)) + { + handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + } } } - // trigger label handlers + // trigger label handlers for exact matches (optional and mandatory) for (auto&& serviceDescriptor : entry.labelMap[MakeFilter(greedyLabel->key, greedyLabel->value)].nodes) { - handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + const auto descriptorLabels = GetLabels(serviceDescriptor); + if(Util::MatchLabels(labels, descriptorLabels)) + { + handler(ServiceDiscoveryEvent::Type::ServiceCreated, serviceDescriptor); + } } } } @@ -126,12 +146,15 @@ void SpecificDiscoveryStore::CallHandlersOnServiceChange(ServiceDiscoveryEvent:: if (greedyLabel == nullptr) { + + bool skipLabelCheck = supplControllerTypeName == controllerTypeRpcServerInternal; // no labels present trigger all - for (auto&& handler : entry.allCluster.handlers) + for (auto&& controllerInfo : entry.allCluster.controllerInfo) { - if (handler) + bool run_handler = skipLabelCheck ? true : Util::MatchLabels(controllerInfo->labels, labels); + if (controllerInfo->handler && run_handler) { - (*handler)(eventType, serviceDescriptor); + controllerInfo->handler(eventType, serviceDescriptor); } } } @@ -139,28 +162,29 @@ void SpecificDiscoveryStore::CallHandlersOnServiceChange(ServiceDiscoveryEvent:: { if (greedyLabel->kind == SilKit::Services::MatchingLabel::Kind::Optional) { - // trigger notlabel handlers - for (auto&& handler : entry.notLabelMap[greedyLabel->key].handlers) + // trigger handlers that do not have the same optional label + for (auto&& controllerInfo : entry.notLabelMap[greedyLabel->key].controllerInfo) { - if (handler) + if (controllerInfo->handler && Util::MatchLabels(controllerInfo->labels, labels)) { - (*handler)(eventType, serviceDescriptor); + controllerInfo->handler(eventType, serviceDescriptor); } } - for (auto&& handler : entry.noLabelCluster.handlers) + // trigger handlers with no labels attached, thus matching our optional label + for (auto&& controllerInfo : entry.noLabelCluster.controllerInfo) { - if (handler) + if (controllerInfo->handler && Util::MatchLabels(controllerInfo->labels, labels)) { - (*handler)(eventType, serviceDescriptor); + controllerInfo->handler(eventType, serviceDescriptor); } } } - // trigger label handlers - for (auto&& handler : entry.labelMap[MakeFilter(greedyLabel->key, greedyLabel->value)].handlers) + // trigger label handlers with exact matches (optional and mandatory) + for (auto&& controllerInfo : entry.labelMap[MakeFilter(greedyLabel->key, greedyLabel->value)].controllerInfo) { - if (handler) + if (controllerInfo->handler && Util::MatchLabels(controllerInfo->labels, labels)) { - (*handler)(eventType, serviceDescriptor); + controllerInfo->handler(eventType, serviceDescriptor); } } } @@ -188,7 +212,7 @@ auto SpecificDiscoveryStore::GetLabelWithMinimalHandlerSet(DiscoveryKeyNode& key { const SilKit::Services::MatchingLabel* outGreedyLabel = nullptr; - size_t matchCount = keyNode.allCluster.handlers.size(); + size_t matchCount = keyNode.allCluster.controllerInfo.size(); // search greedy Cluster guess for (auto&& l : labels) { @@ -197,8 +221,7 @@ auto SpecificDiscoveryStore::GetLabelWithMinimalHandlerSet(DiscoveryKeyNode& key const auto keyTuple = std::make_tuple(l.key, l.value); if (l.kind == SilKit::Services::MatchingLabel::Kind::Mandatory) { - auto& handlers = keyNode.labelMap[keyTuple].handlers; - const auto relevantNodeCount = handlers.size(); + const auto& relevantNodeCount = keyNode.labelMap[keyTuple].controllerInfo.size(); if (relevantNodeCount < matchCount) { matchCount = relevantNodeCount; @@ -207,11 +230,11 @@ auto SpecificDiscoveryStore::GetLabelWithMinimalHandlerSet(DiscoveryKeyNode& key } else if (l.kind == SilKit::Services::MatchingLabel::Kind::Optional) { - auto& fit_handlers = keyNode.labelMap[keyTuple].handlers; - auto& not_label_handlers = keyNode.notLabelMap[l.key].handlers; + const auto labeled_matches = keyNode.labelMap[keyTuple].controllerInfo.size(); + const auto distinct_matches = keyNode.notLabelMap[l.key].controllerInfo.size(); - size_t relevantNodeCount = fit_handlers.size() + not_label_handlers.size(); - if (relevantNodeCount < matchCount) + const size_t relevantNodeCount = labeled_matches + distinct_matches; + if ( relevantNodeCount > 0 && relevantNodeCount < matchCount) { matchCount = relevantNodeCount; outGreedyLabel = &l; @@ -251,7 +274,7 @@ auto SpecificDiscoveryStore::GetLabelWithMinimalNodeSet(DiscoveryKeyNode& keyNod auto& not_label_nodes = keyNode.notLabelMap[l.key].nodes; size_t relevantNodeCount = fit_nodes.size() + not_label_nodes.size(); - if (relevantNodeCount < matchCount) + if ( relevantNodeCount > 0 && relevantNodeCount < matchCount) { matchCount = relevantNodeCount; outGreedyLabel = &l; @@ -292,9 +315,9 @@ void SpecificDiscoveryStore::UpdateDiscoveryClusters(const std::string& controll entry.notLabelMap[l.key].nodes.emplace_back(serviceDescriptor); } // label is seen for the first time (add all earlier handlers to notLabelEntry - for (auto& handler : entry.allCluster.handlers) + for (auto& controllerInfo : entry.allCluster.controllerInfo) { - entry.notLabelMap[l.key].handlers.emplace_back(handler); + entry.notLabelMap[l.key].controllerInfo.emplace_back(controllerInfo); } } } @@ -356,9 +379,38 @@ void SpecificDiscoveryStore::InsertLookupHandler(const std::string& controllerTy const std::vector& labels, ServiceDiscoveryHandler handler) { - auto handlerPtr = std::make_shared(std::move(handler)); + auto controllerInfo = std::make_shared(ControllerCluster(std::move(handler), labels)); UpdateDiscoveryClusters(controllerType_, key, labels, - [handlerPtr](auto& cluster) { cluster.handlers.push_back(handlerPtr); }); + [controllerInfo](auto& cluster) { cluster.controllerInfo.push_back(controllerInfo); }); +} + +const std::vector SpecificDiscoveryStore::GetLabels( + const ServiceDescriptor& descriptor) +{ + + + const auto ctrlType = descriptor.getVal(Core::Discovery::controllerType); + + std::string labelsStr; + + if(ctrlType == controllerTypeDataPublisher) + { + labelsStr = descriptor.getVal(Core::Discovery::supplKeyDataPublisherPubLabels); + } + else if(ctrlType == controllerTypeRpcClient) + { + labelsStr = descriptor.getVal(Core::Discovery::supplKeyRpcClientLabels); + } + else + { + // Don't need labels return an empty vector + return std::vector(); + } + + const auto descriptorLabels = + SilKit::Config::Deserialize>(labelsStr); + return descriptorLabels; + } void SpecificDiscoveryStore::RegisterSpecificServiceDiscoveryHandler( diff --git a/SilKit/source/core/service/SpecificDiscoveryStore.hpp b/SilKit/source/core/service/SpecificDiscoveryStore.hpp index b3ed137f2..b317d980d 100644 --- a/SilKit/source/core/service/SpecificDiscoveryStore.hpp +++ b/SilKit/source/core/service/SpecificDiscoveryStore.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "IServiceDiscovery.hpp" #include "Hash.hpp" @@ -33,12 +34,23 @@ struct FilterTypeHash using HandlerValue = std::shared_ptr; +struct ControllerCluster { + ServiceDiscoveryHandler handler; + std::vector labels; + + ControllerCluster(ServiceDiscoveryHandler ahandler, const std::vector& alabels) : + handler(ahandler), + labels(alabels) { + }; + +}; + //! Stores all potential nodes (service descriptors) and handlers to call for a specific data matching branch class DiscoveryCluster { public: std::vector nodes; - std::vector handlers; + std::vector> controllerInfo; }; //! Holds all relevant information for a controllerType and key (topic/functionName/clientUUID) @@ -102,12 +114,22 @@ class SpecificDiscoveryStore const std::vector& labels, std::function); - //!< Looks for the label that returns a minimal handler set + /*! \brief Looks for the label that returns a minimal handler set + * + * For a suitable controller, ALL its labels must match ALL of our controllers labels + * So we can preselect them via checking which of the controllers labels matches with the least amount of services + * since the others have labels present that are not in the controllers label list, thus they are never going to match. + */ auto GetLabelWithMinimalHandlerSet(DiscoveryKeyNode& keyNode, const std::vector& labels) -> const SilKit::Services::MatchingLabel*; - //!< Looks for the label that returns a minimal ServiceDescriptor set + /*! \brief Looks for the label that returns a minimal ServiceDescriptor set + * + * For a suitable service, ALL its labels must match ALL of our controllers labels + * So we can preselect them via checking which of the stored service labels match with the least amount of handlers + * since the others have labels present that are not in the services label list, they are never going to match. + */ auto GetLabelWithMinimalNodeSet(DiscoveryKeyNode& keyNode, const std::vector& labels) -> const SilKit::Services::MatchingLabel*; @@ -126,6 +148,9 @@ class SpecificDiscoveryStore const std::vector& labels, ServiceDiscoveryHandler handler); + //!< Get serviceDescriptorLabels + const std::vector GetLabels(const ServiceDescriptor& descriptor); + private: //member //!< SpecificDiscoveryStore is only available to a a sub set of controllers const std::unordered_set _allowedControllers = { diff --git a/SilKit/source/core/service/Test_SpecificDiscoveryStore.cpp b/SilKit/source/core/service/Test_SpecificDiscoveryStore.cpp index c567d864d..9eec69aae 100644 --- a/SilKit/source/core/service/Test_SpecificDiscoveryStore.cpp +++ b/SilKit/source/core/service/Test_SpecificDiscoveryStore.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include "gtest/gtest.h" @@ -304,13 +303,13 @@ TEST_F(Test_SpecificDiscoveryStore, lookup_service_discovery_then_handler_labels baseDescriptor.SetSupplementalDataItem(supplKeyDataPublisherMediaType, "text/json"); baseDescriptor.SetSupplementalDataItem(supplKeyDataPublisherPubLabels, "- key: kA\n value: vA\n kind: 2"); - ServiceDescriptor noLabelTestDescriptor{baseDescriptor}; - noLabelTestDescriptor.SetServiceId(1); + ServiceDescriptor testDescriptor{baseDescriptor}; + testDescriptor.SetServiceId(1); - testStore.ServiceChange(ServiceDiscoveryEvent::Type::ServiceCreated, noLabelTestDescriptor); + testStore.ServiceChange(ServiceDiscoveryEvent::Type::ServiceCreated, testDescriptor); - EXPECT_CALL(callbacks, ServiceDiscoveryHandler(ServiceDiscoveryEvent::Type::ServiceCreated, noLabelTestDescriptor)) - .Times(1); + EXPECT_CALL(callbacks, ServiceDiscoveryHandler(ServiceDiscoveryEvent::Type::ServiceCreated, testDescriptor)) + .Times(0); testStore.RegisterSpecificServiceDiscoveryHandler( [this](ServiceDiscoveryEvent::Type discoveryType, const ServiceDescriptor& sd) { diff --git a/SilKit/source/services/pubsub/DataSubscriber.cpp b/SilKit/source/services/pubsub/DataSubscriber.cpp index 877936ab0..c1a293638 100644 --- a/SilKit/source/services/pubsub/DataSubscriber.cpp +++ b/SilKit/source/services/pubsub/DataSubscriber.cpp @@ -31,16 +31,8 @@ void DataSubscriber::RegisterServiceDiscovery() { auto matchHandler = [this](SilKit::Core::Discovery::ServiceDiscoveryEvent::Type discoveryType, const SilKit::Core::ServiceDescriptor& serviceDescriptor) { - auto getVal = [serviceDescriptor](const std::string& key) { - std::string tmp; - if (!serviceDescriptor.GetSupplementalDataItem(key, tmp)) - { - throw SilKitError{"Unknown key in supplementalData"}; - } - return tmp; - }; - const auto pubUUID = getVal(Core::Discovery::supplKeyDataPublisherPubUUID); + const auto pubUUID = serviceDescriptor.getVal(Core::Discovery::supplKeyDataPublisherPubUUID); // Early abort creation if Publisher is already connected if (discoveryType == SilKit::Core::Discovery::ServiceDiscoveryEvent::Type::ServiceCreated @@ -49,28 +41,24 @@ void DataSubscriber::RegisterServiceDiscovery() return; } - const auto topic = getVal(Core::Discovery::supplKeyDataPublisherTopic); - if (topic == _topic) + const auto topic = serviceDescriptor.getVal(Core::Discovery::supplKeyDataPublisherTopic); + + // We need to just match the MediaType, the topic and labels were already prefiltered by the ServiceDiscovery + const std::string pubMediaType{serviceDescriptor.getVal(Core::Discovery::supplKeyDataPublisherMediaType)}; + if (MatchMediaType(_mediaType, pubMediaType)) { - const std::string pubMediaType{getVal(Core::Discovery::supplKeyDataPublisherMediaType)}; - if (MatchMediaType(_mediaType, pubMediaType)) + std::unique_lock lock(_internalSubscribersMx); + + if (discoveryType == SilKit::Core::Discovery::ServiceDiscoveryEvent::Type::ServiceCreated) { - const std::string labelsStr = getVal(Core::Discovery::supplKeyDataPublisherPubLabels); - const std::vector publisherLabels = + const std::string labelsStr = serviceDescriptor.getVal(Core::Discovery::supplKeyDataPublisherPubLabels); + const auto publisherLabels = SilKit::Config::Deserialize>(labelsStr); - if (Util::MatchLabels(_labels, publisherLabels)) - { - std::unique_lock lock(_internalSubscribersMx); - - if (discoveryType == SilKit::Core::Discovery::ServiceDiscoveryEvent::Type::ServiceCreated) - { - AddInternalSubscriber(pubUUID, pubMediaType, publisherLabels); - } - else if (discoveryType == SilKit::Core::Discovery::ServiceDiscoveryEvent::Type::ServiceRemoved) - { - RemoveInternalSubscriber(pubUUID); - } - } + AddInternalSubscriber(pubUUID, pubMediaType, publisherLabels); + } + else if (discoveryType == SilKit::Core::Discovery::ServiceDiscoveryEvent::Type::ServiceRemoved) + { + RemoveInternalSubscriber(pubUUID); } } }; diff --git a/SilKit/source/services/rpc/RpcClient.cpp b/SilKit/source/services/rpc/RpcClient.cpp index 88df9e425..3b539ec3e 100644 --- a/SilKit/source/services/rpc/RpcClient.cpp +++ b/SilKit/source/services/rpc/RpcClient.cpp @@ -55,16 +55,8 @@ void RpcClient::RegisterServiceDiscovery() { auto matchHandler = [this](SilKit::Core::Discovery::ServiceDiscoveryEvent::Type discoveryType, const SilKit::Core::ServiceDescriptor& serviceDescriptor) { - auto getVal = [serviceDescriptor](const std::string& key) { - std::string tmp; - if (!serviceDescriptor.GetSupplementalDataItem(key, tmp)) - { - throw SilKit::StateError{"Unknown key in supplementalData"}; - } - return tmp; - }; - auto clientUUID = getVal(Core::Discovery::supplKeyRpcServerInternalClientUUID); + auto clientUUID = serviceDescriptor.getVal(Core::Discovery::supplKeyRpcServerInternalClientUUID); if (clientUUID == _clientUUID) { diff --git a/SilKit/source/services/rpc/RpcServer.cpp b/SilKit/source/services/rpc/RpcServer.cpp index 3840d876e..5133fc3c8 100644 --- a/SilKit/source/services/rpc/RpcServer.cpp +++ b/SilKit/source/services/rpc/RpcServer.cpp @@ -32,16 +32,7 @@ void RpcServer::RegisterServiceDiscovery() const SilKit::Core::ServiceDescriptor& serviceDescriptor) { if (discoveryType == SilKit::Core::Discovery::ServiceDiscoveryEvent::Type::ServiceCreated) { - auto getVal = [serviceDescriptor](const std::string& key) { - std::string tmp; - if (!serviceDescriptor.GetSupplementalDataItem(key, tmp)) - { - throw SilKit::StateError{"Unknown key in supplementalData"}; - } - return tmp; - }; - - auto clientUUID = getVal(Core::Discovery::supplKeyRpcClientUUID); + auto clientUUID = serviceDescriptor.getVal(Core::Discovery::supplKeyRpcClientUUID); // Early abort creation if Client is already connected if (_internalRpcServers.count(clientUUID) > 0) @@ -49,13 +40,13 @@ void RpcServer::RegisterServiceDiscovery() return; } - auto functionName = getVal(Core::Discovery::supplKeyRpcClientFunctionName); - auto clientMediaType = getVal(Core::Discovery::supplKeyRpcClientMediaType); - std::string labelsStr = getVal(Core::Discovery::supplKeyRpcClientLabels); + auto functionName = serviceDescriptor.getVal(Core::Discovery::supplKeyRpcClientFunctionName); + auto clientMediaType = serviceDescriptor.getVal(Core::Discovery::supplKeyRpcClientMediaType); + std::string labelsStr = serviceDescriptor.getVal(Core::Discovery::supplKeyRpcClientLabels); auto clientLabels = SilKit::Config::Deserialize>(labelsStr); - if (functionName == _dataSpec.FunctionName() && MatchMediaType(clientMediaType, _dataSpec.MediaType()) - && Util::MatchLabels(_dataSpec.Labels(), clientLabels)) + // Match only on the MediaType, FunctionName and Labels are already prefiltered by the DiscoveryService + if (MatchMediaType(clientMediaType, _dataSpec.MediaType())) { AddInternalRpcServer(clientUUID, clientMediaType, clientLabels); } diff --git a/SilKit/source/util/LabelMatching.cpp b/SilKit/source/util/LabelMatching.cpp index 671e58137..6e2b969ac 100644 --- a/SilKit/source/util/LabelMatching.cpp +++ b/SilKit/source/util/LabelMatching.cpp @@ -62,6 +62,7 @@ bool MatchLabels(const std::vector& labels1, const std::vector match }