-
Notifications
You must be signed in to change notification settings - Fork 85
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
Make server::Connection
methods not require &mut self
#186
Comments
quinn's Connection uses Arc<Mutex> under the hood, so if you're holding MutexGuard now, you probably will hold the guard when locking internal states too. |
So, I just wanted to start by bringing in the original design proposal, as it says this:
That was the goal. Is it possible to come up with reasonable solutions that don't compromise? I don't mean to ask for ridiculous workarounds, but to just make sure reasonable ones are explored. For instance, later in that proposal, a |
That is a good point. Would it be possible to remake the accept into a This would allow for simultaneous webtransport and request handling, which is necessary to support more than one |
I think this is not necessary to completely remake Line 151 in c9058fe
|
I have some thoughts on this too. A "receiver" is often exclusive (requires a &mut self) and cannot be cloned, because implementing a receiver with a single Waker and a receiver with multiple Wakers are not at the same level of difficulty. The latter often requires the introduction of some more complex things to manage Waker's offline, such as tokio's (not public) intrusive linked list. Receiving data packets and receiving requests (receiving streams) all have such characteristics. In an asynchronous quic implementation, they are often internally a Receiver. What I mean is that a Quic implementation must take this into account. A quic implementation may makes poll_recv_datagram, poll_recv_bidi_streams receive &mut self. in this case, these APIs provided by quic implementation are very primitive and not easy to use. If developers want to use it to receive streams and do other things at the same time, they have to use Arc themselves and then encapsulate the easy-to-use apis. So it is more likely that QUIC implementations have already implemented this layer of encapsulation, and all they provide are methods that only require &self. In summary, I think it's reasonable to make these methods only require &self. If the quic implementation does not carry out this layer of encapsulation, then it should be done at the compatibility layer between it and h3; if it has already been encapsulated, it would be the best. I know there is a litte flaw with this approach: the method just needs &self, which makes it look like I can receive requests from multiple places at the same time? No. In this regard, we may only be able to make restrictions in the documentation and implementation restrictions - for example, If there is already a task waiting for something that another task is waiting for, it will panic! (This is what our quic implementation does) Another solution is to split connection if possible, just like splitting a bidi stream —— However, it is difficult for the quic implementation to natively support such operations... |
Currently, many methods in
server::Connection
require exclusive access, which makes it nigh impossible to concurrently use the connection.This is not a large problem at the moment, as the only function of interest is the
Connection::accept
method.However, when adding support for the
H3_DATAGRAM
protocol it is not possible to await datagrams and accept requests on the same connection.I ran into this issue when implementing webtransport in #183, which requires datagram support.
In addition, webtransport has support for multiple sessions per connection, which in order to support requires that the connection can be used both for accepting webtransport datagrams and streams and accepting new requests such as
CONNECT
.Simply
Arc<Mutex<Connection>>
does not solve the issue as the MutexGuard would span an await point on accept.Making
Connection::accept
beasync fn accept(&self) -> ...
would solve the issue.Quinn
has a similar api for their accept apis https://docs.rs/quinn/latest/quinn/struct.Connection.htmlIs this a change that we are interested in adding? If so, I could work on it.
The text was updated successfully, but these errors were encountered: