mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2025-02-20 15:14:26 +01:00
Removed PubSubService.h.
This commit is contained in:
parent
b6e75b8fa5
commit
1dfd747b41
@ -1,249 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* @file PubSubService.h
|
|
||||||
* @author An Tao
|
|
||||||
*
|
|
||||||
* Copyright 2018, An Tao. All rights reserved.
|
|
||||||
* https://github.com/an-tao/drogon
|
|
||||||
* Use of this source code is governed by a MIT license
|
|
||||||
* that can be found in the License file.
|
|
||||||
*
|
|
||||||
* Drogon
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <trantor/utils/NonCopyable.h>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <mutex>
|
|
||||||
#include <shared_mutex>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace drogon {
|
|
||||||
using SubscriberID = uint64_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This class template presents an unnamed topic.
|
|
||||||
*
|
|
||||||
* @tparam MessageType
|
|
||||||
*/
|
|
||||||
template <typename MessageType>
|
|
||||||
class Topic : public trantor::NonCopyable {
|
|
||||||
public:
|
|
||||||
using MessageHandler = std::function<void(const MessageType &)>;
|
|
||||||
#if __cplusplus >= 201703L | defined _WIN32
|
|
||||||
using SharedMutex = std::shared_mutex;
|
|
||||||
#else
|
|
||||||
using SharedMutex = std::shared_timed_mutex;
|
|
||||||
#endif
|
|
||||||
/**
|
|
||||||
* @brief Publish a message, every subscriber in the topic will receive the
|
|
||||||
* message.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
*/
|
|
||||||
void publish(const MessageType &message) const {
|
|
||||||
std::shared_lock<SharedMutex> lock(mutex_);
|
|
||||||
for (auto &pair : handlersMap_) {
|
|
||||||
pair.second(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Subcribe to the topic.
|
|
||||||
*
|
|
||||||
* @param handler is invoked when a message arrives.
|
|
||||||
* @return SubscriberID
|
|
||||||
*/
|
|
||||||
SubscriberID subscribe(const MessageHandler &handler) {
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
handlersMap_[++id_] = handler;
|
|
||||||
return id_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Subcribe to the topic.
|
|
||||||
*
|
|
||||||
* @param handler is invoked when a message arrives.
|
|
||||||
* @return SubscriberID
|
|
||||||
*/
|
|
||||||
SubscriberID subscribe(MessageHandler &&handler) {
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
handlersMap_[++id_] = std::move(handler);
|
|
||||||
return id_;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Unsubscribe from the topic.
|
|
||||||
*/
|
|
||||||
void unsubscribe(SubscriberID id) {
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
handlersMap_.erase(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if the topic is empty.
|
|
||||||
*
|
|
||||||
* @return true means there are no subscribers.
|
|
||||||
* @return false means there are subscribers in the topic.
|
|
||||||
*/
|
|
||||||
bool empty() const {
|
|
||||||
std::shared_lock<SharedMutex> lock(mutex_);
|
|
||||||
return handlersMap_.empty();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief Remove all subscribers from the topic.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void clear() {
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
handlersMap_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<SubscriberID, MessageHandler> handlersMap_;
|
|
||||||
mutable SharedMutex mutex_;
|
|
||||||
SubscriberID id_{ 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This class template implements a publish-subscribe pattern with
|
|
||||||
* multiple named topics.
|
|
||||||
*
|
|
||||||
* @tparam MessageType The message type.
|
|
||||||
*/
|
|
||||||
template <typename MessageType>
|
|
||||||
class PubSubService : public trantor::NonCopyable {
|
|
||||||
public:
|
|
||||||
using MessageHandler =
|
|
||||||
std::function<void(const std::string &, const MessageType &)>;
|
|
||||||
#if __cplusplus >= 201703L | defined _WIN32
|
|
||||||
using SharedMutex = std::shared_mutex;
|
|
||||||
#else
|
|
||||||
using SharedMutex = std::shared_timed_mutex;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Publish a message to a topic. The message will be broadcasted to
|
|
||||||
* every subscriber.
|
|
||||||
*/
|
|
||||||
void publish(const std::string &topicName, const MessageType &message) const {
|
|
||||||
std::shared_ptr<Topic<MessageType> > topicPtr;
|
|
||||||
{
|
|
||||||
std::shared_lock<SharedMutex> lock(mutex_);
|
|
||||||
auto iter = topicMap_.find(topicName);
|
|
||||||
if (iter != topicMap_.end()) {
|
|
||||||
topicPtr = iter->second;
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
topicPtr->publish(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Subscribe to a topic. When a message is published to the topic,
|
|
||||||
* the handler is invoked by passing the topic and message as parameters.
|
|
||||||
*/
|
|
||||||
SubscriberID subscribe(const std::string &topicName,
|
|
||||||
const MessageHandler &handler) {
|
|
||||||
auto topicHandler = [topicName, handler](const MessageType &message) {
|
|
||||||
handler(topicName, message);
|
|
||||||
};
|
|
||||||
return subscribeToTopic(topicName, std::move(topicHandler));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Subscribe to a topic. When a message is published to the topic,
|
|
||||||
* the handler is invoked by passing the topic and message as parameters.
|
|
||||||
*/
|
|
||||||
SubscriberID subscribe(const std::string &topicName,
|
|
||||||
MessageHandler &&handler) {
|
|
||||||
auto topicHandler = [topicName, handler = std::move(handler)](
|
|
||||||
const MessageType &message) {
|
|
||||||
handler(topicName, message);
|
|
||||||
};
|
|
||||||
return subscribeToTopic(topicName, std::move(topicHandler));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Unsubscribe from a topic.
|
|
||||||
*
|
|
||||||
* @param topic
|
|
||||||
* @param id The subscriber ID returned from the subscribe method.
|
|
||||||
*/
|
|
||||||
void unsubscribe(const std::string &topicName, SubscriberID id) {
|
|
||||||
{
|
|
||||||
std::shared_lock<SharedMutex> lock(mutex_);
|
|
||||||
auto iter = topicMap_.find(topicName);
|
|
||||||
if (iter == topicMap_.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
iter->second->unsubscribe(id);
|
|
||||||
if (!iter->second->empty())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
auto iter = topicMap_.find(topicName);
|
|
||||||
if (iter == topicMap_.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (iter->second->empty())
|
|
||||||
topicMap_.erase(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief return the number of topics.
|
|
||||||
*/
|
|
||||||
size_t size() const {
|
|
||||||
std::shared_lock<SharedMutex> lock(mutex_);
|
|
||||||
return topicMap_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief remove all topics.
|
|
||||||
*/
|
|
||||||
void clear() {
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
topicMap_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Remove a topic
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void removeTopic(const std::string &topicName) {
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
topicMap_.erase(topicName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Topic<MessageType> > >
|
|
||||||
topicMap_;
|
|
||||||
mutable SharedMutex mutex_;
|
|
||||||
SubscriberID subID_ = 0;
|
|
||||||
SubscriberID subscribeToTopic(
|
|
||||||
const std::string &topicName,
|
|
||||||
typename Topic<MessageType>::MessageHandler &&handler) {
|
|
||||||
{
|
|
||||||
std::shared_lock<SharedMutex> lock(mutex_);
|
|
||||||
auto iter = topicMap_.find(topicName);
|
|
||||||
if (iter != topicMap_.end()) {
|
|
||||||
return iter->second->subscribe(std::move(handler));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::unique_lock<SharedMutex> lock(mutex_);
|
|
||||||
auto iter = topicMap_.find(topicName);
|
|
||||||
if (iter != topicMap_.end()) {
|
|
||||||
return iter->second->subscribe(std::move(handler));
|
|
||||||
}
|
|
||||||
auto topicPtr = std::make_shared<Topic<MessageType> >();
|
|
||||||
auto id = topicPtr->subscribe(std::move(handler));
|
|
||||||
topicMap_[topicName] = std::move(topicPtr);
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace drogon
|
|
Loading…
Reference in New Issue
Block a user