Skip to content

Commit

Permalink
Merge pull request #1058 from ApexAI/iox-#415-add-event-parameter-to-…
Browse files Browse the repository at this point in the history
…find-service

Iox #415 add event parameter to find service
  • Loading branch information
FerdinandSpitzschnueffler authored Feb 4, 2022
2 parents 7290937 + 973d973 commit c73695f
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 133 deletions.
11 changes: 8 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- Introduce `cxx::FunctionalInterface` to enrich nullable classes with `and_then`, `or_else`, `value_or`, `expect` [\#996](https://github.com/eclipse-iceoryx/iceoryx/issues/996)
- Add C++17 `std::perms` as `cxx::perms` to `iceoryx_hoofs/cxx/filesystem.hpp`. [#1059](https://github.com/eclipse-iceoryx/iceoryx/issues/1059)
- Support FreeBSD as a representative for the UNIX platforms [#1054](https://github.com/eclipse-iceoryx/iceoryx/issues/1054)
- Add event parameter to `findService` method [#415](https://github.com/eclipse-iceoryx/iceoryx/issues/415)

**Bugfixes:**

Expand Down Expand Up @@ -240,17 +241,21 @@ capro::ServiceDescription::deserialize(serialisedObj)
});
```
The service-related methods have been moved from `PoshRuntime` to `ServiceDiscovery`. Additionally, the
`offerService` and `stopOfferService` methods have been removed:
The service-related methods have been moved from `PoshRuntime` to `ServiceDiscovery`. The `offerService`
and `stopOfferService` methods have been removed and `findService` has now an additional event paramter:
```cpp
// before
#include "iceoryx_posh/runtime/posh_runtime.hpp"
poshRuntime.offerService(myServiceDescription);
poshRuntime.stopOfferService(myServiceDescription);
poshRuntime.findService({"ServiceA", iox::capro::AnyInstanceString});
// after
serviceDiscovery.findService("ServiceA", Wildcard);
#include "iceoryx_posh/runtime/service_discovery.hpp"
serviceDiscovery.findService("ServiceA", Wildcard, Wildcard);
```

The `iox::cxx::expected` has dropped the requirement for `INVALID_STATE`. With this, the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ class PortManager

const std::atomic<uint64_t>* serviceRegistryChangeCounter() noexcept;
runtime::IpcMessage findService(const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) noexcept;
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) noexcept;

protected:
void makeAllPublisherPortsToStopOffer() noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ class ProcessManager : public ProcessManagerInterface

void findServiceForProcess(const RuntimeName_t& name,
const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) noexcept;
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) noexcept;

void
addInterfaceForProcess(const RuntimeName_t& name, capro::Interfaces interface, const NodeName_t& node) noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ class ServiceRegistry
/// @param[in] searchResult, reference to the vector which will be filled with the results
/// @param[in] service, string or wildcard (= iox::cxx::nullopt) to search for
/// @param[in] instance, string or wildcard (= iox::cxx::nullopt) to search for
/// @param[in] event, string or wildcard (= iox::cxx::nullopt) to search for
void find(ServiceDescriptionVector_t& searchResult,
const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) const noexcept;
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) const noexcept;

/// @brief Returns all service descriptions as copy
/// @return ServiceDescriptionVector_t, copy of complete service registry
Expand All @@ -73,6 +75,7 @@ class ServiceRegistry
/// @todo #859 replace std::multimap with prefix tree
::std::multimap<capro::IdString_t, uint64_t> m_serviceMap;
::std::multimap<capro::IdString_t, uint64_t> m_instanceMap;
::std::multimap<capro::IdString_t, uint64_t> m_eventMap;
ServiceDescriptionVector_t m_serviceDescriptionVector;
};
} // namespace roudi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ class ServiceDiscovery
/// @brief find all services that match the provided service description
/// @param[in] service service string to search for, a nullopt corresponds to a wildcard
/// @param[in] instance instance string to search for, a nullopt corresponds to a wildcard
/// @param[in] event event string to search for, a nullopt corresponds to a wildcard
/// @return cxx::expected<ServiceContainer, FindServiceError>
/// ServiceContainer: on success, container that is filled with all matching instances
/// FindServiceError: if any, encountered during the operation
cxx::expected<ServiceContainer, FindServiceError>
findService(const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) noexcept;
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) noexcept;

/// @brief requests the serviceRegistryChangeCounter from the shared memory
/// @return pointer to the serviceRegistryChangeCounter
Expand Down
5 changes: 3 additions & 2 deletions iceoryx_posh/source/roudi/port_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,12 +559,13 @@ void PortManager::destroySubscriberPort(SubscriberPortType::MemberType_t* const
}

runtime::IpcMessage PortManager::findService(const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) noexcept
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) noexcept
{
runtime::IpcMessage response;

ServiceRegistry::ServiceDescriptionVector_t searchResult;
m_serviceRegistry.find(searchResult, service, instance);
m_serviceRegistry.find(searchResult, service, instance, event);

for (auto& service : searchResult)
{
Expand Down
5 changes: 3 additions & 2 deletions iceoryx_posh/source/roudi/process_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,13 @@ void ProcessManager::updateLivelinessOfProcess(const RuntimeName_t& name) noexce

void ProcessManager::findServiceForProcess(const RuntimeName_t& name,
const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) noexcept
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) noexcept
{
searchForProcessAndThen(
name,
[&](Process& process) {
process.sendViaIpcChannel({m_portManager.findService(service, instance)});
process.sendViaIpcChannel({m_portManager.findService(service, instance, event)});
LogDebug() << "Sent all found services to application " << name;
},
[&]() { LogWarn() << "Unknown process " << name << " requested to find services."; });
Expand Down
11 changes: 9 additions & 2 deletions iceoryx_posh/source/roudi/roudi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ void RouDi::processMessage(const runtime::IpcMessage& message,
}
case runtime::IpcMessageType::FIND_SERVICE:
{
if (message.getNumberOfElements() != 6)
if (message.getNumberOfElements() != 8)
{
LogError() << "Wrong number of parameters for \"IpcMessageType::FIND_SERVICE\" from \"" << runtimeName
<< "\"received!";
Expand All @@ -355,8 +355,10 @@ void RouDi::processMessage(const runtime::IpcMessage& message,
{
cxx::optional<capro::IdString_t> service;
cxx::optional<capro::IdString_t> instance;
cxx::optional<capro::IdString_t> event;
bool isServiceWildcard = false;
bool isInstanceWildcard = false;
bool isEventWildcard = false;
cxx::convert::fromString(message.getElementAtIndex(2).c_str(), isServiceWildcard);
if (!isServiceWildcard)
{
Expand All @@ -367,8 +369,13 @@ void RouDi::processMessage(const runtime::IpcMessage& message,
{
instance.emplace(cxx::TruncateToCapacity, message.getElementAtIndex(5));
}
cxx::convert::fromString(message.getElementAtIndex(6).c_str(), isEventWildcard);
if (!isEventWildcard)
{
event.emplace(cxx::TruncateToCapacity, message.getElementAtIndex(7));
}

m_prcMgr->findServiceForProcess(runtimeName, service, instance);
m_prcMgr->findServiceForProcess(runtimeName, service, instance, event);
}
break;
}
Expand Down
32 changes: 25 additions & 7 deletions iceoryx_posh/source/roudi/service_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ cxx::expected<ServiceRegistry::Error> ServiceRegistry::add(const capro::ServiceD
auto serviceIndex = m_serviceDescriptionVector.size() - 1;
m_serviceMap.insert({serviceDescription.getServiceIDString(), serviceIndex});
m_instanceMap.insert({serviceDescription.getInstanceIDString(), serviceIndex});
m_eventMap.insert({serviceDescription.getEventIDString(), serviceIndex});
return cxx::success<>();
}

Expand Down Expand Up @@ -96,19 +97,21 @@ void ServiceRegistry::remove(const capro::ServiceDescription& serviceDescription
{
removeIndexFromMap(m_serviceMap, index);
removeIndexFromMap(m_instanceMap, index);
removeIndexFromMap(m_eventMap, index);
}
}

void ServiceRegistry::find(ServiceDescriptionVector_t& searchResult,
const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) const noexcept
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) const noexcept
{
cxx::vector<uint64_t, MAX_SERVICE_DESCRIPTIONS> intersection;

ServiceDescriptionVector_t serviceInstanceResult;
// Find (K1, K2)
// O(log n + log n + max(#PossibleServices + #possiblesInstances) + #intersection)
if (instance && service)
{
cxx::vector<uint64_t, MAX_SERVICE_DESCRIPTIONS> intersection;
cxx::vector<uint64_t, MAX_SERVICE_DESCRIPTIONS> possibleServices;
cxx::vector<uint64_t, MAX_SERVICE_DESCRIPTIONS> possibleInstances;

Expand All @@ -132,7 +135,7 @@ void ServiceRegistry::find(ServiceDescriptionVector_t& searchResult,

for (auto& value : intersection)
{
searchResult.push_back(m_serviceDescriptionVector[value]);
serviceInstanceResult.push_back(m_serviceDescriptionVector[value]);
}
}
// Find (*, K2)
Expand All @@ -142,7 +145,7 @@ void ServiceRegistry::find(ServiceDescriptionVector_t& searchResult,
auto range = m_instanceMap.equal_range(instance.value());
for (auto entry = range.first; entry != range.second; ++entry)
{
searchResult.push_back(m_serviceDescriptionVector[entry->second]);
serviceInstanceResult.push_back(m_serviceDescriptionVector[entry->second]);
}
}
// Find (K1, *)
Expand All @@ -152,14 +155,29 @@ void ServiceRegistry::find(ServiceDescriptionVector_t& searchResult,
auto range = m_serviceMap.equal_range(service.value());
for (auto entry = range.first; entry != range.second; ++entry)
{
searchResult.push_back(m_serviceDescriptionVector[entry->second]);
serviceInstanceResult.push_back(m_serviceDescriptionVector[entry->second]);
}
}
else
{
// Find (*, *)
// O(n)
searchResult = m_serviceDescriptionVector;
serviceInstanceResult = m_serviceDescriptionVector;
}

if (event)
{
for (auto iterator = serviceInstanceResult.begin(); iterator != serviceInstanceResult.end(); iterator++)
{
if (iterator->serviceDescription.getEventIDString() == event.value())
{
searchResult.push_back(*iterator);
}
}
}
else
{
searchResult = serviceInstanceResult;
}
}

Expand Down
12 changes: 10 additions & 2 deletions iceoryx_posh/source/runtime/service_discovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ namespace runtime
{
cxx::expected<ServiceContainer, FindServiceError>
ServiceDiscovery::findService(const cxx::optional<capro::IdString_t>& service,
const cxx::optional<capro::IdString_t>& instance) noexcept
const cxx::optional<capro::IdString_t>& instance,
const cxx::optional<capro::IdString_t>& event) noexcept
{
/// @todo #415 remove the string mapping, once the find call is done via shared memory
capro::IdString_t serviceString;
capro::IdString_t instanceString;
capro::IdString_t eventString;
bool isServiceWildcard = !service;
bool isInstanceWildcard = !instance;
bool isEventWildcard = !event;

if (!isServiceWildcard)
{
Expand All @@ -39,11 +42,16 @@ ServiceDiscovery::findService(const cxx::optional<capro::IdString_t>& service,
{
instanceString = instance.value();
}
if (!isEventWildcard)
{
eventString = event.value();
}

IpcMessage sendBuffer;
sendBuffer << IpcMessageTypeToString(IpcMessageType::FIND_SERVICE) << PoshRuntime::getInstance().getInstanceName()
<< cxx::convert::toString(isServiceWildcard) << serviceString
<< cxx::convert::toString(isInstanceWildcard) << instanceString;
<< cxx::convert::toString(isInstanceWildcard) << instanceString
<< cxx::convert::toString(isEventWildcard) << eventString;

IpcMessage requestResponse;

Expand Down
Loading

0 comments on commit c73695f

Please sign in to comment.