void MedianExecutor::onMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp time) { while(buffer->findCRLF()) { const char* crlf = buffer->findCRLF(); std::string response(buffer->peek(), crlf); buffer->retrieveUntil(crlf+2); std::string id(conn->peerAddress().toIpPort().c_str()); LOG_INFO << "MedianExecutor receive: [" << response << "] from " << id; std::vector<std::string> tokens; boost::split(tokens, response, boost::is_any_of(" ")); if(tokens[0] == "random" || tokens[0] == "split") { for(size_t i = 1; i < tokens.size(); ++i) { int64_t n = std::stol(tokens[i]); workerBuffers[id].push_back(n); } } else { LOG_ERROR << "MedianExecutor receive unknown response: [" << response << "] from " << id; conn->shutdown(); } { std::unique_lock<std::mutex> lock(mt); ++workingSize; cond.notify_all(); } } }
void onConnection(const muduo::net::TcpConnectionPtr& conn) { if(conn->connected()) { conn_ = conn; sendRequest(14, false); } else { LOG_INFO << conn->peerAddress().toIpPort() << " is down"; conn->shutdown(); } }
// command: // 1. genNumber n response: ok // 2. average response: number<double> // 3. median response: number<int64_t> // 4. sort response: ok // 5. freq n response: <n1, freq1> <n2, freq2> ... <n, freq> void DataServer::onClientMessage(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buf, muduo::Timestamp time) { while(buf->findCRLF()) { const char* crlf = buf->findCRLF(); std::string command(buf->peek(), crlf); buf->retrieveUntil(crlf+2); std::vector<std::string> tokens; boost::split(tokens, command, boost::is_any_of(" ")); if(command.find("genNumber") == 0) { if(tokens.size() == 3) { GenNumberExecutor executor(connections); dataExecutor = &executor; int64_t number = std::stol(tokens[1]); char mode = tokens[2][0]; executor.execute(number, mode); conn->send("OK\r\n"); } else { conn->send("usage: genNumber [n] [n/u/z]\r\n"); } } else if(command == "average") { AverageExecutor executor(connections); dataExecutor = &executor; double average = executor.execute(); conn->send("average: " + std::to_string(average) + "\r\n"); } else if(command == "median") { MedianExecutor executor(connections); dataExecutor = &executor; int64_t median = executor.execute(); conn->send("median: " + std::to_string(median) + "\r\n"); } else if(command == "sort") { SortExecutor executor(connections); dataExecutor = &executor; executor.execute(); conn->send("OK\r\n"); } else if(command.find("freq") == 0) { size_t freqNumber = std::stoi(tokens[1]); FreqExecutor executor(connections); dataExecutor = &executor; std::vector<std::pair<int64_t, int64_t>> freqs = executor.execute(freqNumber); std::string response = "freqs:"; for(auto& freq : freqs) { response += " " + std::to_string(freq.first) + " " + std::to_string(freq.second); } response += "\r\n"; conn->send(response); } else { LOG_ERROR << "receive unknown command [" << command << "] from " << conn->peerAddress().toIpPort(); conn->shutdown(); } } }