Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new feature needed : suport coroutine for co_yield c++20 #305

Open
asialiugf opened this issue May 9, 2023 · 7 comments
Open

new feature needed : suport coroutine for co_yield c++20 #305

asialiugf opened this issue May 9, 2023 · 7 comments
Labels
enhancement New feature or request need-info Awaiting extra info from community/issue creator

Comments

@asialiugf
Copy link

    client.Select("SELECT id, name FROM default.numbers", [] (const Block& block) -> std::generator<Block>
        {
            for (size_t i = 0; i < block.GetRowCount(); ++i) {
                std::cout << block[0]->As<ColumnUInt64>()->At(i) << " "
                          << block[1]->As<ColumnString>()->At(i) << "\n";
                          co_yield block ;
            }
        }
    );
@ljluestc
Copy link

Would you mind giving more context about what you need to implement?

@asialiugf
Copy link
Author

I have a websocket server eventloop (just one thread for all user, all client sockets, just like node.js) , when the eventloop recieved user's request, it will select data from cliclhouse and response .

one eventloop loops again and again to deal users sockets. (I just call them first loop, second loop ... )

if one user's return data is huge , the other users will be blocked because of one eventloop for all sockets.

so I hope coroutine can help me . for example: if a user's return data from clickhouse is large , the return data can be seperated for several parts to response one by one. after the first part sent back to the user in first loop, the clickhouse select will be coyeild, and then jump to deal the other's request, after first loop end, the eventloop run the second loop. in second loop, the clickhouse select result will be resumed to send next parts of the return data for this user untill all parts be sent.

in coroutine generator, the deal function should have a coroutine return type : std::generator

but here is a lumbda in client.Select( {} ); and I dont kown how to difine the generator.

If you have time, you can refer this:
https://github.com/lewissbaker/generator
an example:

        int intn = 10;
        std::generator<int> g_int = [&]() -> std::generator<int> {
            for (int i = 0; i < intn; i++) co_yield i;
        }();
        size_t count_int = 0;
        auto it_int = g_int.begin();
        for (int i = 0; i < 30; ++i) {
            if (it_int == g_int.end()) break;
            decltype(auto) m_int = *it_int;
            it_int++;
            printf("%d ---- int !!\n", m_int);
        }

thank you !

@1261385937
Copy link
Contributor

A good idea

@1261385937
Copy link
Contributor

1261385937 commented Jun 10, 2023

The checklist :

  1. Async interface is a large feature, a lot of code about network , so i plan to use standalone contrib/asio .
  2. Replace the present code about network (retain the sync interfaces)
  3. Add async interfaces (query, instert and so on)
  4. Provide cluster interfaces (health detection, load balancing writing, etc) based on asynchronous interfaces
  5. Coroutine interfaces based on asio is cheap.

@Enmk Please give me your advice, thanks

@1261385937
Copy link
Contributor

Due to network interaction repeatedly in one requset-response, the async interfaces will use coroutine inside.
So c++20 is necessary, the clickhouse-cpp will go to v3.0 😅

@Enmk
Copy link
Collaborator

Enmk commented Jun 14, 2023

  • Async interface is a large feature, a lot of code about network , so i plan to use standalone contrib/asio .
  • Replace the present code about network (retain the sync interfaces)
  • Add async interfaces (query, instert and so on)
  • Provide cluster interfaces (health detection, load balancing writing, etc) based on asynchronous interfaces
  • Coroutine interfaces based on asio is cheap.

I don't think that health checks (of CH server, I assume) and load balancing (aside from #310) should be implemented in this library.

Also, sine one Client instance means one connection (Client effectively uses one socket), IMO having async interface in the Client itself might be high-effort-low-benefit endeavor.

Perhaps one might want to implement some sort of AsyncClient on top of the Client, using 1 Client per 1 request, in either throw-away manner or have a pool (it is important to re-use only Client instances that didn't raise exceptions). That also doesn't break existing user code and doesn't require a full rewrite of the networking code.

@Enmk Enmk added enhancement New feature or request need-info Awaiting extra info from community/issue creator labels Nov 15, 2023
@kelbon
Copy link

kelbon commented Nov 19, 2024

Due to network interaction repeatedly in one requset-response, the async interfaces will use coroutine inside. So c++20 is necessary, the clickhouse-cpp will go to v3.0 😅

please do not use asio coroutines/ your own coroutines, instead provide callback api, which may be used with any coroutines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request need-info Awaiting extra info from community/issue creator
Projects
None yet
Development

No branches or pull requests

5 participants