Cache Manager for Chat Server

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();
}

Tags: chat server cache management C++

Posted on Thu, 07 May 2026 21:42:46 +0000 by egorig