Adds further ext deps as-is binaries copies from customers env.
Qt6 Migration CI / migrate (push) Canceled after 0s
Qt6 Migration CI / migrate (push) Canceled after 0s
This commit is contained in:
3700 files changed
+2132394
No files matched your search
@@ -0,0 +1,382 @@
|
||||
#pragma once
|
||||
|
||||
#include "ddkit/utils/assert.hpp"
|
||||
#include "ddkit/actors/Key.hpp"
|
||||
#include "ddkit/actors/SessionManager.hpp"
|
||||
#include "ddkit/actors/SessionImpl.hpp"
|
||||
#include "ddkit/actors/SimpleActor.hpp"
|
||||
|
||||
|
||||
namespace ddkit {
|
||||
namespace actors {
|
||||
|
||||
/// @brief The calls (add/create/remove/remove/shutdown/shutdown) from the generated code are delegated here.
|
||||
/// We try to create/remove Actors as much as "normal" as it would be done via Session/Service/Client
|
||||
/// but of course there are some differences, as two calls may create only one Actor etc.
|
||||
/// Keep one SimpleActorPtr as replacement for the not-existing Service/Client-proxys in own list.
|
||||
class BackwardManager {
|
||||
|
||||
public:
|
||||
static BackwardManager& instance();
|
||||
|
||||
/// @brief called from generated code: ObsFactory::add()
|
||||
template <typename Observer>
|
||||
void createObserver(
|
||||
const std::string& serviceName,
|
||||
int domain,
|
||||
bool isService,
|
||||
const std::string& moduleName,
|
||||
typename Observer::TypeUser* callbacks,
|
||||
const std::vector<std::string>& methods,
|
||||
const std::string& clientName = "") {
|
||||
|
||||
DDKIT_LOG_TRACE;
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "add(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< " Please note that it may be removed in future versions.";
|
||||
|
||||
ddkit::log::debug() << "create observer by key api: " << serviceName << ", " << std::to_string(domain);
|
||||
|
||||
checkApiServiceName(serviceName);
|
||||
|
||||
checkObserverType<Observer>();
|
||||
|
||||
ActorConfiguration config(moduleName, isService, domain, serviceName);
|
||||
SimpleActorPtr actor = createOrGetActor(serviceName, domain, isService, moduleName);
|
||||
|
||||
DDKIT_THROW_ON_FALSE_INFO(actor, "Failed to create actor");
|
||||
|
||||
IObserverPtr observer = actor->createObserver<Observer>(*callbacks, methods);
|
||||
|
||||
// if empty there is no need to send data over the wire
|
||||
if (!clientName.empty() && !isService) {
|
||||
actor->setClientName(clientName);
|
||||
}
|
||||
|
||||
// global maps
|
||||
m_observer2actorConfig.insert(std::make_pair(observer, config));
|
||||
typeUser2observerMap<Observer>().insert(std::make_pair(callbacks, observer));
|
||||
}
|
||||
|
||||
/// @brief called from generated code: Factory::create()
|
||||
template <typename Sender>
|
||||
typename Sender::TypeUser* createSender(
|
||||
const std::string& serviceName,
|
||||
int domain,
|
||||
bool isService,
|
||||
const std::string& moduleName,
|
||||
const std::vector<std::string>& methods,
|
||||
const std::string& clientName = "") {
|
||||
|
||||
DDKIT_LOG_TRACE;
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "create(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< "Please note that it may be removed in future versions.";
|
||||
|
||||
ddkit::log::debug() << "create sender by key api: " << moduleName;
|
||||
|
||||
checkApiServiceName(serviceName);
|
||||
|
||||
checkSenderType<Sender>();
|
||||
|
||||
ActorConfiguration config(moduleName, isService, domain, serviceName);
|
||||
SimpleActorPtr actor = createOrGetActor(serviceName, domain, isService, moduleName);
|
||||
|
||||
DDKIT_THROW_ON_FALSE_INFO(actor, "Failed to create actor");
|
||||
|
||||
ISenderPtr isender = actor->createSender<Sender>(methods);
|
||||
|
||||
DDKIT_THROW_ON_FALSE_INFO(isender, "BackwardManager::createSender: could not create sender");
|
||||
|
||||
// if empty there is no need to send data over the wire
|
||||
if (!clientName.empty()) {
|
||||
actor->setClientName(clientName);
|
||||
}
|
||||
|
||||
// return raw-ptr for old C-API
|
||||
Sender* sender = dynamic_cast<Sender*>(isender.get()); // downcast - Sender inherits ISender
|
||||
DDKIT_THROW_ON_FALSE(sender);
|
||||
typename Sender::TypeUser* senderUser = sender; // upcast - Sender inherits IService/IClient
|
||||
|
||||
// global maps
|
||||
std::unique_lock<std::recursive_mutex> lockMaps(m_mutex);
|
||||
m_sender2actorConfig.insert(std::make_pair(isender, config));
|
||||
|
||||
typeUser2senderMap<Sender>().insert(std::make_pair(senderUser, isender));
|
||||
|
||||
return senderUser;
|
||||
}
|
||||
|
||||
/// @brief called from generated code: ObsFactory::remove()
|
||||
template <typename Observer>
|
||||
void removeObserverByObserverUser(
|
||||
typename Observer::TypeUser* observerUser, bool isService, const std::string& moduleName) {
|
||||
|
||||
DDKIT_LOG_TRACE;
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "remove(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< "Please note that it may be removed in future versions.";
|
||||
|
||||
ddkit::log::debug() << "Remove Observer By Observer User: " << moduleName;
|
||||
|
||||
{
|
||||
checkObserverType<Observer>();
|
||||
|
||||
DDKIT_THROW_ON_FALSE_INFO(observerUser, interfaceNameApi(isService, moduleName) + "ObsFactory::remove()"
|
||||
+ " called with Observer* == nullptr ?");
|
||||
|
||||
// global maps
|
||||
DDKIT_THROW_ON_FALSE_INFO(typeUser2observerMap<Observer>().find(observerUser) != typeUser2observerMap<Observer>().end(),
|
||||
interfaceNameApi(isService, moduleName) + "ObsFactory::remove()"
|
||||
+ " called with Observer* not given to " + interfaceNameApi(isService, moduleName)
|
||||
+ "ObsFactory::add*() before? (or removed twice?)");
|
||||
|
||||
IObserverPtr observer = typeUser2observerMap<Observer>().at(observerUser);
|
||||
DDKIT_THROW_ON_FALSE_INFO(observer, "removeObserverByObserverUser: observer not found");
|
||||
|
||||
ActorConfiguration config = m_observer2actorConfig.at(observer);
|
||||
ddkit::log::debug() << "called Obs...remove() on " << config;
|
||||
|
||||
DDKIT_THROW_ON_FALSE(config.isService == isService);
|
||||
DDKIT_THROW_ON_FALSE(config.module == moduleName);
|
||||
|
||||
// global maps
|
||||
m_observer2actorConfig.erase(observer);
|
||||
typeUser2observerMap<Observer>().erase(typeUser2observerMap<Observer>().find(observerUser));
|
||||
|
||||
SessionImplPtr sessionImpl = findSession(config.domain);
|
||||
if (sessionImpl) {
|
||||
SimpleActorPtr actor = sessionImpl->findActor(config.serviceName, config.isService, config.module);
|
||||
if (actor) {
|
||||
if (actor->hasSender()) {
|
||||
ddkit::log::warn() << "The actor still has a sender, the observer will be deleted after sender is also destoryed!"
|
||||
<< " Consider using the OO-Api.";
|
||||
} else {
|
||||
auto it = m_config2actor.find(config);
|
||||
if (it != m_config2actor.end()) {
|
||||
if (m_config2actor.at(config) == actor) {
|
||||
m_config2actor.erase(it);
|
||||
|
||||
actor->shutdown();
|
||||
|
||||
// wait until dispatcher etc are done.
|
||||
while (actor.use_count() > 1) {
|
||||
ddkit::utils::system::msSleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sessionImpl.reset(); // local hold ptr
|
||||
removeSessionIfEmpty(config.domain);
|
||||
}
|
||||
}
|
||||
checkIfEmpty();
|
||||
}
|
||||
|
||||
/// @brief called from generated code: Factory::remove()
|
||||
template <typename Sender>
|
||||
void removeSenderBySenderUser(typename Sender::TypeUser* senderUser, bool isService, const std::string& moduleName) {
|
||||
DDKIT_LOG_TRACE;
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "remove(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< "Please note that it may be removed in future versions.";
|
||||
|
||||
ddkit::log::debug() << "RemoveSender By Sender User: " << moduleName;
|
||||
|
||||
{
|
||||
checkSenderType<Sender>();
|
||||
|
||||
DDKIT_THROW_ON_FALSE_INFO(senderUser, interfaceNameApi(isService, moduleName) + "Factory::remove()"
|
||||
+ " called with Sender* == nullptr ?");
|
||||
// global maps
|
||||
DDKIT_THROW_ON_FALSE_INFO(typeUser2senderMap<Sender>().find(senderUser) != typeUser2senderMap<Sender>().end(),
|
||||
interfaceNameApi(isService, moduleName) + "Factory::remove()"
|
||||
+ " called with Sender* not received from " + interfaceNameApi(isService, moduleName)
|
||||
+ "Factory::create() before? (or removed twice?)");
|
||||
|
||||
ISenderPtr sender = typeUser2senderMap<Sender>().at(senderUser);
|
||||
DDKIT_THROW_ON_FALSE_INFO(sender, "Sender not found");
|
||||
|
||||
ActorConfiguration config = m_sender2actorConfig.at(sender);
|
||||
ddkit::log::debug() << "called ...remove() on " << config;
|
||||
DDKIT_THROW_ON_FALSE(config.isService == isService);
|
||||
DDKIT_THROW_ON_FALSE(config.module == moduleName);
|
||||
|
||||
// remove sender from global maps
|
||||
m_sender2actorConfig.erase(sender);
|
||||
typeUser2senderMap<Sender>().erase(typeUser2senderMap<Sender>().find(senderUser));
|
||||
|
||||
SessionImplPtr sessionImpl = findSession(config.domain);
|
||||
if (sessionImpl) {
|
||||
SimpleActorPtr actor = sessionImpl->findActor(config.serviceName, config.isService, config.module);
|
||||
if (actor) {
|
||||
actor->discardSender();
|
||||
if (actor->hasObserver()) {
|
||||
// still has a observer dont shutdown actor!
|
||||
ddkit::log::warn() << "There is still a observer, make sure to delete it too."
|
||||
<< " Consider using the new OO-Api.";
|
||||
} else {
|
||||
ddkit::log::debug() << "Does not have a observer, we can shutdown the actor.";
|
||||
auto configIt = m_config2actor.find(config);
|
||||
if (configIt != m_config2actor.end()) {
|
||||
if (m_config2actor.at(config) == actor) {
|
||||
m_config2actor.erase(configIt);
|
||||
|
||||
actor->shutdown();
|
||||
|
||||
// wait until dispatcher etc are done.
|
||||
while (actor.use_count() > 1) {
|
||||
ddkit::utils::system::msSleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sessionImpl.reset(); // local hold session-ptr
|
||||
removeSessionIfEmpty(config.domain);
|
||||
}
|
||||
}
|
||||
checkIfEmpty();
|
||||
}
|
||||
|
||||
/// @brief called from generated code: ObsFactory::shutdown()
|
||||
template <typename Observer>
|
||||
void shutdownObservers(bool isService, const std::string& moduleName) {
|
||||
DDKIT_LOG_TRACE;
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "shutdown(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< "Please note that it may be removed in future versions.";
|
||||
|
||||
ddkit::log::debug() << "shutdown observers: " << moduleName;
|
||||
|
||||
checkObserverType<Observer>();
|
||||
typedef typename Observer::TypeUser TypeUser;
|
||||
|
||||
std::vector<TypeUser*> observerUsers;
|
||||
for (auto& p : typeUser2observerMap<Observer>()) {
|
||||
observerUsers.push_back(p.first);
|
||||
}
|
||||
for (TypeUser* typeUser : observerUsers) {
|
||||
removeObserverByObserverUser<Observer>(typeUser, isService, moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief called from generated code: Factory::shutdown()
|
||||
template <typename Sender>
|
||||
void shutdownSenders(bool isService, const std::string& moduleName) {
|
||||
DDKIT_LOG_TRACE;
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "shutdown(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< "Please note that it may be removed in future versions.";
|
||||
|
||||
ddkit::log::debug() << "Shutdown senders: " << moduleName;
|
||||
|
||||
checkSenderType<Sender>();
|
||||
typedef typename Sender::TypeUser TypeUser;
|
||||
|
||||
std::vector<TypeUser*> senderUsers;
|
||||
for (auto& p : typeUser2senderMap<Sender>()) {
|
||||
senderUsers.push_back(p.first);
|
||||
}
|
||||
for (TypeUser* typeUser : senderUsers) {
|
||||
removeSenderBySenderUser<Sender>(typeUser, isService, moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief called from generated code: ObsFactory::getSource()
|
||||
template <typename Observer>
|
||||
std::string getSource(bool isService, const std::string& moduleName) {
|
||||
|
||||
DDKIT_LOG_TRACE;
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
ddkit::log::warn() << "getSource(): You are using the deprecated C-Style API. "
|
||||
<< "It is recommended to upgrade to the new object-oriented API. "
|
||||
<< "Please note that it may be removed in future versions. "
|
||||
<< "Use ddkit::actors::CallbackInfo::current(); instead.";
|
||||
|
||||
CallbackInfo callbackInfo = SessionManager::instance().callbackInfo();
|
||||
|
||||
bool isToServiceReal = callbackInfo.isFromClient;
|
||||
|
||||
if (isService != isToServiceReal) {
|
||||
ddkit::log::warn() << "getSource() was called on ObsFactory of " << interfaceNameApi(isService, moduleName)
|
||||
<< " but callback right now is sending data to "
|
||||
<< serviceClientNameApi(isToServiceReal, moduleName) << ". Probably one should use \""
|
||||
<< interfaceNameApi(isToServiceReal, moduleName) << "ObsFactory\" instead of \""
|
||||
<< interfaceNameApi(isService, moduleName) << "ObsFactory\", to remove this warning.";
|
||||
}
|
||||
|
||||
// as "source" we gave back the serviceName or the clientId, depending on the side
|
||||
if (callbackInfo.isFromClient) {
|
||||
// client called service
|
||||
return callbackInfo.clientName; // this is sendingActor (=clientActorId) or user-given clientName
|
||||
} else {
|
||||
// service called client
|
||||
return callbackInfo.serviceName;
|
||||
}
|
||||
}
|
||||
|
||||
SessionImplPtr createOrGetSession_(int domain);
|
||||
|
||||
bool isClean() const;
|
||||
|
||||
private:
|
||||
std::recursive_mutex m_mutex;
|
||||
std::map<int, SessionImplPtr> m_domain2session;
|
||||
std::map<ActorConfiguration, SimpleActorPtr> m_config2actor; // holding Actors exactly as long, as add/create/remove tells
|
||||
|
||||
// Pointers to actors-configs
|
||||
std::map<IObserverPtr, ActorConfiguration> m_observer2actorConfig;
|
||||
std::map<ISenderPtr, ActorConfiguration> m_sender2actorConfig;
|
||||
|
||||
BackwardManager();
|
||||
~BackwardManager();
|
||||
|
||||
SimpleActorPtr createOrGetActor(const std::string& serviceName, int domain, bool isService, const std::string& moduleName);
|
||||
SessionImplPtr findSession(int domain);
|
||||
SessionImplPtr createOrGetSession(int domain);
|
||||
void removeSessionIfEmpty(int domain);
|
||||
void checkIfEmpty();
|
||||
|
||||
// these functions are used to circumvent the fact das data members cant be templated
|
||||
// which is only somewhat fine since BackwardManger is a singleton class
|
||||
template <typename Sender> std::map<typename Sender::TypeUser*, ISenderPtr>& typeUser2senderMap() {
|
||||
static std::map<typename Sender::TypeUser*, ISenderPtr> s_typeUser2sender;
|
||||
return s_typeUser2sender;
|
||||
}
|
||||
|
||||
template <typename Observer> std::map<typename Observer::TypeUser*, IObserverPtr>& typeUser2observerMap() {
|
||||
static std::map<typename Observer::TypeUser*, IObserverPtr> s_typeUser2observer;
|
||||
return s_typeUser2observer;
|
||||
}
|
||||
|
||||
// no copying
|
||||
BackwardManager(BackwardManager const&) = delete;
|
||||
BackwardManager(BackwardManager&&) = delete;
|
||||
void operator=(BackwardManager const&) = delete;
|
||||
};
|
||||
|
||||
} // namespace actors
|
||||
} // namespace ddkit
|
||||
Reference in new issue
Block a user