A coroutines based connection pool written in C++.
This library uses coroutines and requires C++20. The library is tested using gcc10. If you would like to use the library in vscode, consider using the devcontainer at https://github.com/cblauvelt/docker-vscode-cpp
If you are using conan you can simply type
conan create .If you're not using conan, you can simply copy the include files into your project.
Using the TCP Connection. See the test directory for how the echo server works.
awaitable<void> slow_client_test(boost::asio::io_context& ctx) {
cpool::tcp_connection connection(ctx, "localhost", slow_port_number);
connection.set_state_change_handler(
std::bind(on_connection_state_change, std::placeholders::_1));
auto error = co_await connection.connect();
EXPECT_FALSE(error);
size_t bytes = 0;
std::string message = "Test message";
auto delay = 500ms;
std::tie(error, bytes) =
co_await connection.write(boost::asio::buffer(message));
std::vector<std::uint8_t> buf(256);
connection.expires_after(delay);
std::tie(error, bytes) = co_await connection.read(boost::asio::buffer(buf));
connection.expires_never();
error = co_await connection.disconnect();
ctx.stop();
}
void main() {
boost::asio::io_context io_context(1);
boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
signals.async_wait([&](auto, auto) { io_context.stop(); });
co_spawn(io_context, echo_listener(port_number), detached);
cout << "Listening on " << port_number << endl;
for (int i = 0; i < num_tests - 1; i++) {
co_spawn(io_context, client_test(std::ref(io_context)), detached);
}
co_spawn(io_context, client_test(std::ref(io_context), true), detached);
io_context.run();
}Using the connection pool
awaitable<void> echo_connection_test(asio::io_context& ctx) {
auto connection_creator = [&]() -> std::unique_ptr<tcp_connection> {
return std::make_unique<tcp_connection>(ctx, "localhost", port_number);
};
auto pool =
connection_pool<tcp_connection>(connection_creator, num_connections);
auto connection = co_await pool.get_connection();
std::string message = "Test message";
auto [err, bytes] =
co_await connection->write(boost::asio::buffer(message));
std::vector<std::uint8_t> buf(256);
std::tie(err, bytes) =
co_await connection->read_some(boost::asio::buffer(buf));
auto bufferMessage = bytes_to_string(buf | std::views::take(bytes));
pool.release_connection(connection);
connection = nullptr;
ctx.stop();
}
void main() {
asio::io_context ctx(1);
co_spawn(ctx, echo_listener(port_number), detached);
co_spawn(ctx, echo_connection_test(std::ref(ctx)), detached);
ctx.run();
}