#ifndef __TopListServerConnection_h_ #define __TopListServerConnection_h_ #include #include "../shared/ServerConnection.h" #include "UserInfo.h" /* This is responsible for sending top list requests to the dedicated top list * server. The top list server replaces the database, but it's also got a lot * of "business logic" in it. It takes in a high level request from the client * and takes care of looking up the data, formatting, periodically repeating, * etc. * * Currently this is a slave to TopList.C. Some requests are still processed * using the database. Others are sent to the new server. TopList.C has to * break open some of the requests to see who they belong to. Even when the * database goes away, we might have different server connections for handling * different historical requests. So one unit will still have to receive all * top list requests, and decide who to send them to. And that same unit will * have to deal with the requests to cancel a previous request. */ class TopListServerConnection : public ForeverServerConnection, private ThreadMonitor::Extra { private: enum { mtOpenChannel, mtStart, mtStop }; static const int CI_FORWARD = 1; const std::string _startCommand; const std::string _stopCommand; struct Request { bool metadataSent; bool saveToMru; std::string collaborate; Request() : metadataSent(false) { } }; typedef std::map< std::string, Request > RequestByWindowId; struct ClientInfo { SocketInfo *socket; ExternalRequest::MessageId messageId; UserId userId; RequestByWindowId requests; ClientInfo() : socket(NULL), userId(0) { } }; typedef std::map< SocketInfo::SerialNumber, ClientInfo > BySocket; BySocket _bySocket; // This set never goes away. I'm trying to find all users still using this // old feature so they can be upgraded. I plan to report each user to the // log once, but not ever again. (This set is empty each time we restart // the server.) std::unordered_set< UserId > _knownUsers; // Overriding ThreadMonitor::Extra virtual std::string getInfoForThreadMonitor(); void requestData(TalkWithServer *talkWithServer, SocketInfo *socket, RequestByWindowId::const_iterator request); void requestData(SocketInfo *socket, std::string const &collaborate, std::string const &windowId, bool saveToMru); void stopData(SocketInfo *socket, std::string const &windowId); void stopData(SocketInfo *socket); void repeatAllDataRequests(TalkWithServer *talkWithServer); // From IContainerThreadUser virtual void socketClosed(SocketInfo *socket); // From IContainerThreadUser virtual void initializeInThread(); // From TalkWithServer::IMessageListener virtual void onMessage(std::string bytes, int clientId, TalkWithServer::CancelId cancelId); // From ServerConnection virtual void onNewConnection(TalkWithServer *talkWithServer); // From ServerConnection virtual bool shouldTryToConnect(); public: TopListServerConnection(bool delayed); // These are thread safe. void openChannel(SocketInfo *socket, ExternalRequest::MessageId messageId); void newTopList(SocketInfo *socket, std::string const &collaborate, std::string const &windowId, bool saveToMru); void cancelTopList(SocketInfo *socket, std::string const &windowId); }; #endif