/** * Testing overloading the listener and how much can it handle. */ #include #include #include #include "Address.hpp" #include "protocol/quicr/QuicrConnection.hpp" #include "protocol/quicr/QuicrEndpoint.hpp" #include "protocol/quicr/QuicrConnectionListener.hpp" using namespace tw::net; using namespace tw::net::quicr; std::atomic is_stopped(false); void got_signal(int) { is_stopped.store(true); } void register_signal_handler() { struct sigaction sa; memset( &sa, 0, sizeof(sa) ); sa.sa_handler = got_signal; sigfillset(&sa.sa_mask); sigaction(SIGINT,&sa,NULL); } int main() { register_signal_handler(); // spdlog::set_pattern("[%H:%M:%S] [thread %t] %v"); const int NUM_CONNECTIONS = 500; std::thread server_thread([&]() { auto server_endpoint_r = QuicrEndpoint::create(); assert(server_endpoint_r); auto server_endpoint = std::move(*server_endpoint_r); assert(server_endpoint->bind(8100)); auto listen_r = QuicrConnectionListener::listen(server_endpoint.get()); assert(listen_r); auto listen = std::move(listen_r.value()); struct ConnectionTestSession { QuicrConnection *connection; bool is_answered; std::vector buffer; ConnectionTestSession(QuicrConnection *connection) : connection(connection), is_answered(false), buffer(1024 * 16) {} }; std::unordered_map connections; uint32_t answered_count = 0; uint32_t num_connections = 0; while(answered_count < NUM_CONNECTIONS) { if(is_stopped) break; server_endpoint->poll(); auto new_connection = listen->listen(); if(new_connection) { connections[new_connection->address()] = new ConnectionTestSession(new_connection); num_connections++; spdlog::warn("Num connections: {}", num_connections); } for(auto& connection : connections) { // assert(!connection.second->is_answered); auto read_r = connection.second->connection->read_into(connection.second->buffer); assert(read_r); if(connection.second->is_answered) { continue; } std::string mesg(connection.second->buffer.begin(), connection.second->buffer.begin() + *read_r); std::transform(mesg.begin(), mesg.end(), mesg.begin(), ::toupper); connection.second->connection->send_message(std::as_writable_bytes(std::span(mesg)), true); connection.second->is_answered = true; answered_count++; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } spdlog::warn("DONE: got all answers"); }); std::vector> endpoints(NUM_CONNECTIONS); std::vector connections(NUM_CONNECTIONS); std::vector established_counts(NUM_CONNECTIONS, false); for(int i = 0; i < NUM_CONNECTIONS; i++) { endpoints[i] = QuicrEndpoint::create().value(); connections[i] = endpoints[i]->connect(Address{"127.0.0.1", 8100}).value(); } std::atomic established_count(0); spdlog::info("Starting overload test with {} connections", NUM_CONNECTIONS); while(!is_stopped && established_count.load() < NUM_CONNECTIONS) { for(int i = 0; i < NUM_CONNECTIONS; i++) { { endpoints[i]->poll(); } if(!established_counts[i] && connections[i]->state() == QuicrConnectionState::Established) { established_counts[i] = true; established_count++; } } } server_thread.join(); return 0; }