71 lines
2.0 KiB
C++
71 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include "ddkit/actors/Session.hpp"
|
|
#include "ddkit/actors/MonitorSession.hpp"
|
|
#include <unordered_map>
|
|
#include <memory>
|
|
#include <mutex>
|
|
|
|
namespace ddkit {
|
|
namespace actors {
|
|
|
|
class SessionFactory {
|
|
|
|
public:
|
|
/// @brief static
|
|
static SessionFactory& instance() {
|
|
static SessionFactory instance;
|
|
return instance;
|
|
}
|
|
|
|
std::shared_ptr<ddkit::actors::Session> getSession(int domain);
|
|
std::shared_ptr<ddkit::actors::MonitorSession> getMonitorSession(int domain);
|
|
|
|
bool isClean() const;
|
|
private:
|
|
template <typename T>
|
|
std::shared_ptr<T> get(int& domain, std::unordered_map<int, std::weak_ptr<T>>& map) {
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
auto it = map.find(domain);
|
|
if (it != map.end()) {
|
|
auto session_ptr = it->second.lock();
|
|
if (session_ptr) {
|
|
// Return existing session
|
|
return session_ptr;
|
|
}
|
|
}
|
|
|
|
// Create new session
|
|
auto session = std::shared_ptr<T>(
|
|
new T(domain),
|
|
[domain, &map, this](T* s) {
|
|
delete s;
|
|
cleanup(domain, map);
|
|
});
|
|
map[domain] = session;
|
|
return session;
|
|
}
|
|
|
|
template <typename T>
|
|
void cleanup(int domain, std::unordered_map<int, std::weak_ptr<T>>& map) {
|
|
// clean up
|
|
std::lock_guard<std::mutex> lock(m_mutex);
|
|
// We only erase if the weak pointer is expired, indicating no active shared_ptr exists.
|
|
auto it = map.find(domain);
|
|
if (it != map.end() && it->second.expired()) {
|
|
map.erase(it);
|
|
}
|
|
}
|
|
|
|
SessionFactory() = default;
|
|
SessionFactory(const SessionFactory&) = delete;
|
|
SessionFactory& operator=(const SessionFactory&) = delete;
|
|
|
|
std::unordered_map<int, std::weak_ptr<ddkit::actors::Session>> m_sessions;
|
|
std::unordered_map<int, std::weak_ptr<ddkit::actors::MonitorSession>> m_monitorSessions;
|
|
std::mutex m_mutex;
|
|
};
|
|
|
|
}
|
|
}
|