Giter VIP home page Giter VIP logo

rzbdz / libcoring Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 0.0 1.4 MB

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: MIT License

CMake 0.33% C++ 99.67%
proactor asyncio webserver cpp20 io-uring-cpp io-uring coroutine

libcoring's Introduction

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 some documents available:

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

Getting Start

Just take a look at the directory demo.

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_await buffer_pool.try_read_block(conn, GID, MAX_MESSAGE_LEN);
    selected_buffer_resource return_it_when_exit(selected);
    co_await socket_writer(conn, selected).write_all_to_file();
  }
}
task<> event_loop() {
  co_await buffer_pool.provide_group_contiguous(buf, MAX_MESSAGE_LEN, BUFFERS_COUNT, GID);
  while (true) {
    auto conn = co_await acceptor.accept();
    coro::spawn(echo_loop(conn));
  }
}
void run(){
  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() {
  using namespace std::chrono_literals;
  auto endpoint = net::endpoint::from_resolve("www.google.com", 80);
  std::cout << endpoint.address_str() << std::endl;
  auto conn = co_await tcp::connect_to(endpoint, 3s); // timer in kernel, it would throw an exception if timeout
  // ... do sth with conn
  // ....................
  co_await timeout(20s); // timer in user space , see coring/test/io_context_test.cpp
                         // with coroutine, this is natual
  // ... do sth else
  // ....................
}

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

cancellation:

Notice: since IORING_ASYNC_CANCEL_ANY in 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) {
  using namespace std::chrono_literals;
  io_cancel_source src;
  auto ep = net::endpoint::from_resolve("www.google.com", 80);
  // non-blocking, fire-and-forget, async_task
  auto promise = 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_await ioc->timeout(3s);
  if (!promise.is_ready()) {
    auto res = co_await src.cancel_and_wait_for_result(*ioc);
    // res is 0 if successfully cancelled
  }
  [[maybe_unused]] auto c = co_await promise; 
  // here may throw if cancelled, I didn't decide if we should count ECLEAN as an exception
}

For more details, check getting start file.


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. Check benchmark page 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 like insert_iterator with 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 coroutine task<> is lazy in libcoring, just like the awaitable<> in boost::asio, arguments on lazy task<> or non-lazy task<> both make sense, the difference is only in the initial_suspend function, 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.


libcoring's People

Contributors

rzbdz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

libcoring's Issues

memory leak without cancellation

When io_context destructs, theasync_scope is not co_await joined , thus the coroutine frame on heap might not be cleaned when the detached coroutine is not finished.

see: https://togithub.com/CarterLi/liburing4cpp/issues/27
see: https://en.cppreference.com/w/cpp/coroutine/coroutine_handle/destroy
see: https://stackoverflow.com/questions/68352718/is-it-necessary-to-call-destroy-on-a-stdcoroutine-handle

A possible solution for cancellation (I 've seen this before, maybe in boost.asio)

cancellation_source src  (just like stop_source & stop_token, and the cancellation token is supported in Task of C#)
awaitable frame 1: a cancellation_token bind to the src
  awaitable frame 2: a cancellation_token bind to the src
   awaitable frame 3: a cancellation_token bind to the src
    .....
      io_uring/user space timer/thread_pool a cancellation_token bind to the src

Once the coroutine calling stack (stackless linked-list of coroutine_handles) is suspended by a io event (on io_uring/user space timer/thread_pool ), say this awaitable could be a non-lazy task (thus we have a eager started future concept(check here), it's start to run asynchrounously, but there is no need to wait), then we just pass the user_data of io_uring or some timer token of timer or some thread_pool token of thread_pool to the original src, thus all the awaitable along the calling stack could get a token bind the a same user_data or sth (just like what shared_ptr does), then we got O(1) complexity to update the user_data along the way, but when it comes to the when_all supports, it fails.

More investigation and trying would be done.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.