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

[draft] add support for asio CompletionToken api for client #97

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

0x00002a
Copy link
Contributor

@0x00002a 0x00002a commented Jan 1, 2022

This implements support for the asio CompletionToken api as discussed in #74.

There are some issues currently with coroutines. The only compiler I can get working with them currently is gcc and it won't compile one of the tests (it crashes with an ICE). There is an example using coroutines, but it throws a bad_alloc exception with an unreadable stack trace, I'm not sure if this is an issue with how I wrote the example or asio.

Major breaking changes

  • client::controller::http_connect no longer accepts a visitor, instead if the filter has a single body type it accepts a completion token for a response with that body, otherwise a completion token with a variant of responses over the possible bodies. This means that code currently using callbacks and filters with more than 1 body (i.e. a custom one, none of the ones packaged with malloy currently use this) need to add a call to std::visit
  • client::controller::http_connect no longer returns a std::future<error_code>, instead it is contained in the completion token. This means every user currently using a callback token (all of them) needs to add another argument. The reason it originally returned a future was to prevent the user having to write the same boilerplate every time to wait on the result without running off the end of main and without waiting forever on an error. However, the future behavior can be restored by passing asio::use_future and then adding a try...catch around the .get(), which is what I have done for the examples

Other major changes

  • websocket::connection::[accept, send, read, connect] now use CompletionToken for the template type, allowing one to pass for example asio::use_future and have the return be a future rather than invoking a callback

Notable internal changes

  • action_queue now uses a custom action polymorphic interface for the stored actions. This is in order to allow non-copyable CompletionTokens as converting to std::function causes a copy (as I discovered). While this does require the explicit allocation of a unique_ptr I believe it actually results in fewer allocations overall as std::function has a lot of hidden ones. This does mean websocket::connection has some additional boilerplate but I consider this a reasonable tradeoff for the api it now provides
  • asio::async_initiate is now used to enable the CompletionToken api. One gotcha with it is that the type passed to the handler function is not the same as the CompletionToken type, and is not guaranteed to by copyable (although it is always moveable)
  • client::http::connection has changed a bit, run has been removed with its arguments being moved to the constructor. start is now called to start it. I originally tried to remove it completely but due to shared_from_this it can only be started after the call to make_shared is complete. Honestly I am not particularly happy with connection in its current form, as it isn't really a standalone class and is essentially just a complex delegate that should be an implementation detail of controller imo (unlike websocket::connection for example, which is completely usable standalone).

Things that could use improvement (IMO)

  • Should controller::stop also use this api? It might be doable but is more complex because of the weird inheritance stuff going on with it
  • Not sure if there should be variants of the tests for use_future, there is one currently for websockets but I'm not sure if there is any advantage to more (and the disadvantage is effectively duplicate code with only minor differences)

@Tectu
Copy link
Owner

Tectu commented Jan 2, 2022

Wow... that is a substantial amount of work...
I'll have a proper look at this today/tomorrow/... (should be fine as I should have a lot more time at hand the next few weeks).

One thing I noticed while just browsing this: It would seem that the Ubuntu test-suites on boost versions >= 1.74.0 hang (from the quick looks of it if it's either a shared build or a TLS-enabeld build (?)).
This would be similar to #89

@Tectu Tectu mentioned this pull request Jan 7, 2022
@Tectu
Copy link
Owner

Tectu commented Apr 27, 2022

@0x00002a any news/update on this? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants