CacheManager
The cache manager stores caches for notification messages and chat messages. Because users may be offline, when a friend sends a message or a group mesage is sent, those messages cannot be delivered to the user. Therefore, messages are first sent to the cache manager. When the user comes online, the cached messages are pushed to the user from the cache manager.
Code
Notification message cache:
struct NotifyMsgCache
{
int32_t userid;
std::string notifymsg;
};
Chat message cache:
struct ChatMsgCache
{
int32_t userid;
std::string chatmsg;
};
Both caches pair a user ID with a string.
Cache Manager
Both notification messages and chat messages are stored using a list.
Main functions include adding and retrieving notification message caches, as well as adding and retrieving chat message caches.
class MsgCacheManager final
{
public:
MsgCacheManager();
~MsgCacheManager();
MsgCacheManager(const MsgCacheManager& rhs) = delete;
MsgCacheManager& operator =(const MsgCacheManager& rhs) = delete;
bool AddNotifyMsgCache(int32_t userid, const std::string& cache);
void GetNotifyMsgCache(int32_t userid, std::list<NotifyMsgCache>& cached);
bool AddChatMsgCache(int32_t userid, const std::string& cache);
void GetChatMsgCache(int32_t userid, std::list<ChatMsgCache>& cached);
private:
std::list<NotifyMsgCache> m_listNotifyMsgCache; // Notification message cache, e.g., friend request messages
std::mutex m_mtNotifyMsgCache;
std::list<ChatMsgCache> m_listChatMsgCache; // Chat message cache
std::mutex m_mtChatMsgCache;
};
The implementation details are as follows:
Adding a cache:
Convert the user ID and the cache message string into a NotifyMsgCache or ChatMsgCache struct. The string is appended with its length. Finally, insert it in to the list.
Retrieving a cache:
Iterate through the list, find entries matching the user ID, and place them into the provided list reference cached. The retrieved entries are then removed from the internal list.
#include "../base/logging.h"
#include "MsgCacheManager.h"
MsgCacheManager::MsgCacheManager()
{
}
MsgCacheManager::~MsgCacheManager()
{
}
bool MsgCacheManager::AddNotifyMsgCache(int32_t userid, const std::string& cache)
{
std::lock_guard<std::mutex> guard(m_mtNotifyMsgCache);
NotifyMsgCache nc;
nc.userid = userid;
nc.notifymsg.append(cache.c_str(), cache.length());
m_listNotifyMsgCache.push_back(nc);
LOG_INFO << "append notify msg to cache, userid: " << userid << ", m_mapNotifyMsgCache.size() : " << m_listNotifyMsgCache.size() << ", cache length : " << cache.length();
// TODO: persist to disk or database to prevent loss on crash
return true;
}
void MsgCacheManager::GetNotifyMsgCache(int32_t userid, std::list<NotifyMsgCache>& cached)
{
std::lock_guard<std::mutex> guard(m_mtNotifyMsgCache);
for (auto iter = m_listNotifyMsgCache.begin(); iter != m_listNotifyMsgCache.end(); )
{
if (iter->userid == userid)
{
cached.push_back(*iter);
iter = m_listNotifyMsgCache.erase(iter);
}
else
{
iter++;
}
}
LOG_INFO << "get notify msg cache, userid: " << userid << ", m_mapNotifyMsgCache.size(): " << m_listNotifyMsgCache.size() << ", cached size: " << cached.size();
}
bool MsgCacheManager::AddChatMsgCache(int32_t userid, const std::string& cache)
{
std::lock_guard<std::mutex> guard(m_mtChatMsgCache);
ChatMsgCache c;
c.userid = userid;
c.chatmsg.append(cache.c_str(), cache.length());
m_listChatMsgCache.push_back(c);
LOG_INFO << "append chat msg to cache, userid: " << userid << ", m_listChatMsgCache.size() : " << m_listChatMsgCache.size() << ", cache length : " << cache.length();
// TODO: persist to disk or database to prevent loss on crash
return true;
}
void MsgCacheManager::GetChatMsgCache(int32_t userid, std::list<ChatMsgCache>& cached)
{
std::lock_guard<std::mutex> guard(m_mtChatMsgCache);
for (auto iter = m_listChatMsgCache.begin(); iter != m_listChatMsgCache.end(); )
{
if (iter->userid == userid)
{
cached.push_back(*iter);
iter = m_listChatMsgCache.erase(iter);
}
else
{
iter++;
}
}
LOG_INFO << "get chat msg cache, no cache, userid: " << userid << ",m_listChatMsgCache.size(): " << m_listChatMsgCache.size() << ", cached size: " << cached.size();
}