-
Notifications
You must be signed in to change notification settings - Fork 9
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
[Bug] websocket::connection::read does not interleave with websocket::connection::send #70
Comments
I'm not 100% on this. It seems it is valid for there to be an async read/write pair active at the same time (according to the comment linked below). What I said above about the read coming in before the write is true, but if there can be a read and write active it can't be the issue. It is still a problem to call If this is still valid, and I've interpreted it right, it might be better to have two queues, one for reads and one for writes. But that increases the complexity by quite a bit and I can't think of a use case for it. Thoughts? |
I vote for adding this (the queueing of all everything that is). I also suggest that if we don't add it, we should remove it from We might want to also offer some sort of "ejection" mechanism, where the user can get access to the |
I'm sorry, I will get back to you on this shortly - I'm not ignoring it! |
Sorry for not getting back on this sooner. I really needed to implement In general I think having a command queue is a good design choice as for some of the reasons you outlined/mentioned. However, there are some caveats in my opinion. Currently I am mainly thinking of Doesn't seem like a simple design choice to me :p But I do heavily agree that we should have consistency between read & write operations. Either both have a queue or neither (the queue might be the same for both read & write operations (along with the remaining actions/operations). |
Didn't think of that one, good point. imo Also, it is ok to call
|
Having I take it that we must not have more than one |
I've got the branch fix-ws-interleaved-io which needs some work and updating based on this discussion, but I can work on it when I get back or possibly this week. I've been experimenting with coroutines recently and I think I can make a "queued actions" container, which would greatly simplify adding queues for each action type (read, write, close, etc). Currently this is impeded by the fact that the async callback has to tell the next action to execute but only after its completely done, which is simply not possible to wrap with nested callbacks, unless I'm missing something. If I did end up using coroutines they would not need to be exposed in the interface but they would have to be used for all the stuff wrapped (async_read, async_write, etc). Is it acceptable to add coroutine code to malloy currently? |
Last time I checked compiler support for coroutines were pretty... bad. I definitely see the beauty of using coroutines in
|
Moving everything to coroutines might be quite the job. Mostly thinking of the problems mentioned in #40. Also we might have to roll a few of our own coroutines as I'm personally leaning more toward having coroutines (in the interface) in the release after |
Update on this, its on my todo list but I'm very busy currently, so it'll probably be a few days before I can finish this off |
So I'm almost done with this, but I've run into a pretty major issue. clang is not compatible with libstdc++'s coroutine header (llvm bug report). The linked issue does have a hack to that might allow it to work but its a pretty big "might", and I don't like the idea of putting it in a library header. The other option is using libc++. Unfortunately as discussed in #46, libc++ does not support concepts until v13 (which isn't released yet). So we're kinda stuck. Personally I quite like the idea of just dropping clang support until 13 is released and/or it catches up with gcc or msvc in terms of supported features. This isn't great as it means clang based tools, which is most of C++ tooling afaik, are unreliable/don't work at all. @Tectu Do you currently need clang support? iirc you need it to replace mingw? |
lol, this is hideous. I am currently not relying on I do need to build This hurts, it really does. It feels wrong - very much so. But I do think that dropping |
Just to be clear, are you talking about |
Yes, I am talking about Moving everything (i.e. the applications consuming Changes which break this behavior would be a problem for me.
Nah, you didn't mess up anything in my opinion. Your contributions to this project have great value and are highly appreciated :) |
Well thank you, I appreciate it. Turns out I didn't turn off the mingw CI after all, I just relabelled it as clang instead, presumably because I was going to switch it and then didn't :p. In other news, I've run into another few issues. After a few hours of staring at link errors I found this buried in asio: boostorg/asio@2e7b0be, which stops it building on boost < 1.76 + msvc and also this problem in gcc 10.3, which I can't reproduce but which matches the link errors shown by the CI, and stops it building on msys/mingw. I'm starting to wonder if it might be better to implement a hacky solution now, which doesn't use coroutines but allows easy upgrading to them, rather than trying to get them to work with the current implementations. |
I guess that is what we get for dealing with "bleeding edge" C++ 🙈 How hacky would the hacky solution be? |
Off the top of my head, I was thinking the callbacks could be passed a function to call when done. Its not great because its an obscure runtime bug waiting to happen if a line of code is forgotten but its not terrible imo |
Well, this is a C++ library after all so preventing the user from shooting him or herself in the foot is not always possible. |
Fixes #70 * chore: added test to repro issue (somewhat accurately) * chore: basic framework for interleaved setup * fix: lifetime issues with queued read * feat: make websocket::connection threadsafe * chore: add action queue * fix: action_queue * chore: compile fixes * feat: add seperate queues for read and writes for ws * chore: make rest of connection threadsafe * fix: lifetime of captures for callbacks * feat: add connection::force_disconnect * chore: add tests for force_disconnect * fix: test error code assertions * fix: msvc build * fix: websocket force_disconnect test checks being platform-dependent * chore: misc cleanup and comments * fix: msys ci incorrect naming * fix: gcc < 11 build * chore: drop clang from CI * chore: remove coroutine usage * fix: lifetime issues with action_queue * chore: add completiontoken support to websocket::stream * chore: cleanup and format * chore: post -> dispatch for action_queue * chore: revert "drop clang from CI" This reverts commit a1e2df5 * chore: revert "msys ci incorrect naming"
This is mostly for tracking. I'm currently working on a fix and have a test which repros it (ish, see below)
Currently
send
's are queued up and executed in order by the websocket connection, making it much easier for users since they do not need to worry about manually syncing them. However,read
is not interleaved or indeed queued at all, which is somewhat suprisingly behaviour (to me anyway on encountering it). The result of read not being properly interleaved is that it is possible to callsend
and thenread
but have theread
block waiting for messages before the send ever goes through (which can result in both peers trying to read and the connection shutting down).Due to the nature of the bug (relies on send not being dispatched before the read call is hit), its a pain to reproduce, and the test I've created only reproduces it some of the time.
The text was updated successfully, but these errors were encountered: