mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
work on write queue/flow control
This commit is contained in:
@@ -102,7 +102,15 @@ public:
|
||||
}
|
||||
|
||||
void command_error(connection_ptr connection,const std::string msg) {
|
||||
connection->send("{\"type\":\"error\",\"value\":\""+msg+"\"}");
|
||||
websocketpp::message::data_ptr m = connection->get_data_message();
|
||||
|
||||
if (m) {
|
||||
m->reset(frame::opcode::TEXT);
|
||||
m->set_payload("{\"type\":\"error\",\"value\":\""+msg+"\"}");
|
||||
connection->send(m);
|
||||
} else {
|
||||
// error no avaliable message buffers
|
||||
}
|
||||
}
|
||||
|
||||
// close: - close this connection
|
||||
@@ -128,41 +136,53 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
long milli_seconds = get_ms(m_epoch);
|
||||
|
||||
std::stringstream update;
|
||||
update << "{\"type\":\"stats\""
|
||||
<< ",\"timestamp\":" << milli_seconds
|
||||
<< ",\"connections\":" << m_broadcast_handler->get_connection_count()
|
||||
<< ",\"admin_connections\":" << m_connections.size()
|
||||
<< ",\"messages\":[";
|
||||
|
||||
const msg_map& m = m_broadcast_handler->get_message_stats();
|
||||
|
||||
msg_map::const_iterator msg_it;
|
||||
msg_map::const_iterator last = m.end();
|
||||
if (m.size() > 0) {
|
||||
last--;
|
||||
}
|
||||
|
||||
for (msg_it = m.begin(); msg_it != m.end(); msg_it++) {
|
||||
update << "{\"id\":" << (*msg_it).second.id
|
||||
<< ",\"hash\":\"" << (*msg_it).second.hash << "\""
|
||||
<< ",\"sent\":" << (*msg_it).second.sent
|
||||
<< ",\"acked\":" << (*msg_it).second.acked
|
||||
<< ",\"size\":" << (*msg_it).second.size
|
||||
<< ",\"time\":" << (*msg_it).second.time
|
||||
<< "}" << (msg_it == last ? "" : ",");
|
||||
}
|
||||
|
||||
update << "]}";
|
||||
|
||||
m_broadcast_handler->clear_message_stats();
|
||||
|
||||
typename std::set<connection_ptr>::iterator it;
|
||||
|
||||
for (it = m_connections.begin(); it != m_connections.end(); it++) {
|
||||
(*it)->send(update.str(),false);
|
||||
if (m_connections.size() > 0) {
|
||||
long milli_seconds = get_ms(m_epoch);
|
||||
|
||||
std::stringstream update;
|
||||
update << "{\"type\":\"stats\""
|
||||
<< ",\"timestamp\":" << milli_seconds
|
||||
<< ",\"connections\":" << m_broadcast_handler->get_connection_count()
|
||||
<< ",\"admin_connections\":" << m_connections.size()
|
||||
<< ",\"messages\":[";
|
||||
|
||||
const msg_map& m = m_broadcast_handler->get_message_stats();
|
||||
|
||||
msg_map::const_iterator msg_it;
|
||||
msg_map::const_iterator last = m.end();
|
||||
if (m.size() > 0) {
|
||||
last--;
|
||||
}
|
||||
|
||||
for (msg_it = m.begin(); msg_it != m.end(); msg_it++) {
|
||||
update << "{\"id\":" << (*msg_it).second.id
|
||||
<< ",\"hash\":\"" << (*msg_it).second.hash << "\""
|
||||
<< ",\"sent\":" << (*msg_it).second.sent
|
||||
<< ",\"acked\":" << (*msg_it).second.acked
|
||||
<< ",\"size\":" << (*msg_it).second.size
|
||||
<< ",\"time\":" << (*msg_it).second.time
|
||||
<< "}" << (msg_it == last ? "" : ",");
|
||||
}
|
||||
|
||||
update << "]}";
|
||||
|
||||
m_broadcast_handler->clear_message_stats();
|
||||
|
||||
typename std::set<connection_ptr>::iterator it;
|
||||
|
||||
websocketpp::message::data_ptr msg = (*m_connections.begin())->get_data_message();
|
||||
|
||||
if (msg) {
|
||||
msg->reset(frame::opcode::TEXT);
|
||||
|
||||
msg->set_payload(update.str());
|
||||
|
||||
for (it = m_connections.begin(); it != m_connections.end(); it++) {
|
||||
(*it)->send(msg);
|
||||
}
|
||||
} else {
|
||||
// error no avaliable message buffers
|
||||
}
|
||||
}
|
||||
|
||||
m_timer->expires_from_now(boost::posix_time::milliseconds(250));
|
||||
|
||||
@@ -90,17 +90,14 @@ public:
|
||||
}
|
||||
|
||||
void on_message(connection_ptr connection,message::data_ptr msg) {
|
||||
typename std::set<connection_ptr>::iterator it;
|
||||
|
||||
wscmd::cmd command = wscmd::parse(msg->get_payload());
|
||||
wscmd::cmd command = wscmd::parse(msg->get_payload());
|
||||
|
||||
if (command.command == "ack") {
|
||||
handle_ack(connection,command);
|
||||
connection->recycle(msg);
|
||||
} else {
|
||||
broadcast_message(msg);
|
||||
}
|
||||
|
||||
connection->recycle(msg);
|
||||
}
|
||||
|
||||
void command_error(connection_ptr connection,const std::string msg) {
|
||||
@@ -160,11 +157,15 @@ public:
|
||||
|
||||
typename std::set<connection_ptr>::iterator it;
|
||||
|
||||
// broadcast to clients
|
||||
// broadcast to clients
|
||||
for (it = m_connections.begin(); it != m_connections.end(); it++) {
|
||||
(*it)->send(msg->get_payload(),(msg->get_opcode() == frame::opcode::BINARY));
|
||||
//(*it)->send(msg->get_payload(),(msg->get_opcode() == frame::opcode::BINARY));
|
||||
for (int i = 0; i < 100; i++) {
|
||||
(*it)->send(msg);
|
||||
}
|
||||
|
||||
}
|
||||
new_msg.sent = m_connections.size();
|
||||
new_msg.sent = m_connections.size()*100;
|
||||
new_msg.acked = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,26 +49,37 @@ int main(int argc, char* argv[]) {
|
||||
bool tls = false;
|
||||
|
||||
// 12288 is max OS X limit without changing kernal settings
|
||||
const rlim_t ideal_size = 100000;
|
||||
const rlim_t ideal_size = 10000;
|
||||
rlim_t old_size;
|
||||
rlim_t old_max;
|
||||
|
||||
struct rlimit rl;
|
||||
int result;
|
||||
|
||||
result = getrlimit(RLIMIT_NOFILE, &rl);
|
||||
if (result == 0) {
|
||||
std::cout << "cur: " << rl.rlim_cur << " max: " << rl.rlim_max << std::endl;
|
||||
//std::cout << "System FD limits: " << rl.rlim_cur << " max: " << rl.rlim_max << std::endl;
|
||||
|
||||
old_size = rl.rlim_cur;
|
||||
|
||||
old_max = rl.rlim_max;
|
||||
|
||||
if (rl.rlim_cur < ideal_size) {
|
||||
rl.rlim_cur = ideal_size;
|
||||
//rl.rlim_cur = rl.rlim_max;
|
||||
result = setrlimit(RLIMIT_NOFILE, &rl);
|
||||
std::cout << "Attempting to raise system file descriptor limit from " << rl.rlim_cur << " to " << ideal_size << std::endl;
|
||||
rl.rlim_cur = ideal_size;
|
||||
|
||||
if (result != 0) {
|
||||
std::cout << "Unable to request an increase in the file descripter limit. This server will be limited to " << old_size << " concurrent connections. Error code: " << errno << std::endl;
|
||||
}
|
||||
if (rl.rlim_max < ideal_size) {
|
||||
rl.rlim_max = ideal_size;
|
||||
}
|
||||
|
||||
result = setrlimit(RLIMIT_NOFILE, &rl);
|
||||
|
||||
if (result == 0) {
|
||||
std::cout << "Success" << std::endl;
|
||||
} else if (result == EPERM) {
|
||||
std::cout << "Failed. This server will be limited to " << old_size << " concurrent connections. Error code: Insufficient permissions. Try running process as root. system max: " << old_max << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed. This server will be limited to " << old_size << " concurrent connections. Error code: " << errno << " system max: " << old_max << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +108,11 @@ int main(int argc, char* argv[]) {
|
||||
plain_handler_ptr h(new websocketpp::broadcast::server_handler<plain_endpoint_type>());
|
||||
plain_endpoint_type e(h);
|
||||
|
||||
e.alog().set_level(websocketpp::log::alevel::ALL);
|
||||
e.elog().set_level(websocketpp::log::elevel::ALL);
|
||||
e.alog().unset_level(websocketpp::log::alevel::ALL);
|
||||
e.elog().unset_level(websocketpp::log::elevel::ALL);
|
||||
|
||||
e.alog().set_level(websocketpp::log::alevel::DEVEL);
|
||||
|
||||
std::cout << "Starting WebSocket broadcast server on port " << port << std::endl;
|
||||
e.listen(port);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user