-
Notifications
You must be signed in to change notification settings - Fork 380
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
RequestServer.Serve bugs found looking at PR-361 #363
Conversation
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 all looks good. I'll mark this for 1.12.0?
Anything else you wanted to add to this before merging?
No, I don’t think so. There’s a bit of a hope to avoid touching as much as possible, so as little can break as possible. 😆 |
@@ -158,8 +160,7 @@ func (rs *RequestServer) Serve() error { | |||
|
|||
err := rs.serveLoop(pktChan) | |||
|
|||
close(pktChan) // shuts down sftpServerWorkers | |||
wg.Wait() // wait for all workers to exit | |||
wg.Wait() // wait for all workers to exit |
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.
Won't this wait forever now?
The previous sequence seems more correct, since you usually close the channels so workers can detect end of record stream and exit. The you wait for the exit.
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.
The pktChan
is closed as a defer
in the rs.serveLoop(pktChan)
.
Specifically here: https://github.com/pkg/sftp/pull/363/files#diff-412115c53c6c5fea203e8253f32d2645R110
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.
Ah yes, I overlooked somehow that the function has been factored out. So the changes you did are completely correct in this regard.
I just did a quick test and it seems fine for me, all my test cases passed and also manual checking for transfer errors seems ok, thanks! |
:grumble-grumble: merge conflicts when a delete and a delete/insert end up head-to-tail next to each other. |
@eikenb this seems now good to go. Wanna merge it? |
I’m usually hesitant to commit my own merges if there are no other checks on code. But sure, I think everyone is pretty satisfied that this |
So, I end up moving the “tautological statement” into a function under
Request
(transferError(err error)
). The new function better encapsulates behavior of theRequest
object to calls on theRequest
object. So, while the check now still exists, it at least is an appropriate guard statement, guarding against potential misbehavior.The thing I noticed during PR-361, is that the
break
in theswitch { default: … }
does not break out of thefor { … }
loop, but rather only out of theswitch
. Meaning, thebreak
as it originally appeared was actually a no-op, and execution wasn’t properly ending in that situation.The solution was to move the
for { … }
loop into its own independent function, where the loop can then be broken clearly and unambiguously with areturn
.Additionally, I noticed that although we’re looping over
openRequests
, which is supposed to only be accessed under lock, we were not actually holding the lock at that point.As well,
Request.Close
really should be closing both thereaderAt
and thewriterAt
if they implement,io.Closer
, even if the first one returns anerr != nil
error.