Skip to content

libcoring is a C++ network library in Proactor, and it is based on the new io_uring syscall of linux and coroutine in C++ 20. It's stop currently. We will try to bring sender-receiver model to it in the future.

License

Notifications You must be signed in to change notification settings

rzbdz/libcoring

Repository files navigation

What 's this:

libcoring is a C++ network library in Proactor pattern (@see: POSA2), and it is based on the new io_uring syscall of linux and coroutine in C++ 20. It's under development now, the progress could be viewed in Github project page.

There are somedocumentsavailable:

  • For an overview of development document or to know how libcoring is arranged, please refer todesign document file.
  • To build and run this library with demos, checkgetting startfile. Installation and library import/link configuration isn't available yet for it's still developing.

Getting Start

Just take a look at the directorydemo.

echo server:

//codes are trimmed, check the source `coring/demo/echo_server.cpp` for details
task<>echo_loop(tcp::connection conn){
while(true){
auto& selected =co_awaitbuffer_pool.try_read_block(conn, GID, MAX_MESSAGE_LEN);
selected_buffer_resourcereturn_it_when_exit(selected);
co_awaitsocket_writer(conn, selected).write_all_to_file();
}
}
task<>event_loop() {
co_awaitbuffer_pool.provide_group_contiguous(buf, MAX_MESSAGE_LEN, BUFFERS_COUNT, GID);
while(true) {
autoconn =co_awaitacceptor.accept();
coro::spawn(echo_loop(conn));
}
}
voidrun(){
io_context context;
context.schedule(event_loop());
context.run();
}

timeout:

//codes are trimmed, check the source `coring/demo/connect_with_timeout.cpp` for details
task<>connect() {
usingnamespacestd::chrono_literals;
autoendpoint =net::endpoint::from_resolve("google",80);
std::cout << endpoint.address_str() << std::endl;
autoconn =co_awaittcp::connect_to(endpoint, 3s);//timer in kernel, it would throw an exception if timeout
//... do sth with conn
//....................
co_awaittimeout(20s);//timer in user space, see coring/test/io_context_test.cpp
//with coroutine, this is natual
//... do sth else
//....................
}

voidrun() {
io_context context;
context.schedule(connect(&context));
context.run();
}

cancellation:

Notice: sinceIORING_ASYNC_CANCEL_ANYin io_uring will soon be released, the development on cancellation part of libcoring stalls now. The cancellation branch would be marked decrapted and be deleted soon. By the time the new kernel is available, the development would go on with another branch. Codes below may be not supported or supported in newer versions.

task<>connect(io_context *ioc) {
usingnamespacestd::chrono_literals;
io_cancel_source src;
autoep =net::endpoint::from_resolve("google",80);
//non-blocking, fire-and-forget, async_task
autopromise =tcp::connect_to(ep, src.get_token());
//I can just do many other things here, say do some O(n^2) computing...
//......
//use this for simplicity, user space timer is low cost-effective here...
co_awaitioc->timeout(3s);
if(!promise.is_ready()) {
autores =co_awaitsrc.cancel_and_wait_for_result(*ioc);
//res is 0 if successfully cancelled
}
[[maybe_unused]]autoc =co_awaitpromise;
//here may throw if cancelled, I didn't decide if we should count ECLEAN as an exception
}

For more details, checkgetting startfile.


Performance

Now the comparison is focus on the overhead of the utilities and coroutine abstraction in libcoring, when it comes to io_uring versus epoll/... is another topics. Currently, only httpd and echo-server is benched. Checkbenchmarkpage for details.

Without SQPoll, compared to raw C liburing interface (100%):

utility QPS Throughput
webbench (120 bytes) 102% 99%
apache bench (120 bytes) 101% 102%
rust-echo-bench (512 bytes) 96% N/A
rust-echo-bench (2018 bytes) 102% N/A

Focusing on now

  • [*now] Benchmarking for all module with alternatives designs.
  • Threading, no good threading model design now.
  • more simple buffer interface, and improve the performance on sth likeinsert_iteratorwith fmt.
  • [suspended]Cancellation for io_uring.

Notices and Concerns:

This project learn from following library or repositories:

This project learn and modified some codes from following library or repositories:

The type of coroutinetask<>is lazy in libcoring, just like theawaitable<>in boost::asio, arguments on lazytask<>or non-lazytask<>both make sense, the difference is only in theinitial_suspendfunction, I would try to find which is better design, maybe lazy task cooperate with executor would be enough:

The cancellation for io_uring and combined with stackless coroutine would be a little difficult to image. There are mature solution in C# await and async facilities, but IOCP differs to io_uring on both cancellation and multithreading restrictions. Although a simple cancellation token could be used for coroutine, but the supports for io_uring would be another subject. Another things is that the cancellation part in io_uring is still keep going, recently the CANCEL_ANY is patched, cancellation is now supporting cancel more than one request a time (use a fd). But it requires a further upgrade of latest kernel, I would try once it's available.


About

libcoring is a C++ network library in Proactor, and it is based on the new io_uring syscall of linux and coroutine in C++ 20. It's stop currently. We will try to bring sender-receiver model to it in the future.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published