-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
fix(sources): Shutdown starting from tcp
and unix
sockets
#2618
Conversation
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
I think there's an issue: users will be able to submit data to the TCP connections, get a TCP ACK for their data, and when shutdown signal comes and we discard all the data that's still left in the kernel buffers. |
Did some digging, and it seems like But still, we should even without involving shutdown - I think we should at least try to attempt to the whole kernel-buffered data up until the underlying socket returns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great! I noticed a few issues though, let's discuss!
That would just delay the problem, there is always a window of time between receiving WouldBlock and shutting down the connection, in which OS could receive more data which we would lose. The only way that I see to avoid any loss is to close the connection without dropping it so we can read until the end. But
@MOZGIII do you have some other idea? |
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
Right, but when socket is closed - we can't read anymore...
In essence, we want to 1) consume the stuff that's at the receive queue for a socket, but 2) without letting the kernel accepting any new data. We could easily do (1), but not the (2). Yeah, I'm not sure it's something we can achieve with raw TCP... So, I think what we have currently is good! 👍 |
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blockers are addressed. This is now mergable IMO, addressing the rest is optional.
Let's wait for @bruceg before merging, maybe he has an idea on how to get those bytes in OS buffers. |
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
Can we do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this allow_read_until
trait approach, looks good.
Technically, we can do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is always a window of time between receiving WouldBlock and shutting down the connection, in which OS could receive more data which we would lose.
The only way that I see to avoid any loss is to close the connection without dropping it so we can read until the end.
Yes, we need to do the inverse of #2429 here. Basically, the receiver can signal to the sender that it should stop writing by closing its own write half of the socket. The sender detects this when read
returns EOF and it can then finish sending and close its own end of the socket. The server can then read until EOF on its end and no data is lost.
@lukesteensen Didn't know that was the convention. Do you have an idea on how common it is? I ask so to determine should we add a timer for such connections with duration shorter than the shutdown timer, something like a few seconds, or just to rely on the shutdown timer for those that don't follow it. |
This looks like it’s a protocol layer atop of TCP. I would expect the receiver closing the write end asap, rather than when it’s done reading. It’s a clever way to implement the required signalling atop of a protocol that doesn’t implement it, but I think it’s a non-standard contract. The downside is we can’t really automatically detect if that contract is respected by a particular sender. Looks like we can use it by default though, and if it works - it works, if it doesn’t - well, nothing breaks, and we just fallback to the scenario equivalent to the current situation. |
I'm not sure I'd call it an entire protocol, but I agree it is at least a simple convention on top of TCP. Depending on the socket implementation, it does give a much more graceful closure within the TCP protocol itself. You are right that we can't ensure the client follows that convention, but there is no harm in trying and it degrades to exactly the same situation as before if they do not. |
Good question, I am not entirely sure 😄 I would think that something on the order of 5 seconds should be long enough to wait. It's probably not wise to assume most clients will follow that convention. |
I think a shutdown timer is reasonable. :) 5 seconds is plenty generous. |
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
A timeout was already added in #278. It's configurable through Latest commit contains a test and a fix for |
Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com>
…dotdev#2618) * Add ReadUntil Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Fix mock source Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Fix mock source Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Rename Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Rename struct Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Simplify assert Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Trigger write shutdown Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Add test & fix TcpSink Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Remove stray comment Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> * Bump Signed-off-by: Kruno Tomola Fabro <krunotf@gmail.com> Signed-off-by: Brian Menges <brian.menges@anaplan.com>
Closes #2604.
Adds
ReadUntil
forAsyncRead
similar toTakeUntil
forStream
.This wraps
tcp
andunix
sockets withReadUntil
andShutdownSignal
. So once the shutdown starts there will be no more reads from the sockets, but all that have been read will be processed.This also fixes
mock
source.