Skip to content

Commit

Permalink
Add timeout for session.Wait
Browse files Browse the repository at this point in the history
session.Wait() can hand indefinitely, this adhoc solution pivots after
5 seconds of waiting time.

t.session is now also checked for nil, which led to panic in rare cases.

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
  • Loading branch information
Paulo Gomes committed Mar 25, 2022
1 parent b9d3b76 commit c2b58f0
Showing 1 changed file with 31 additions and 4 deletions.
35 changes: 31 additions & 4 deletions pkg/git/libgit2/managed/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import (
"net/url"
"runtime"
"strings"
"time"

"golang.org/x/crypto/ssh"

Expand Down Expand Up @@ -214,14 +215,40 @@ func (t *sshSmartSubtransport) Action(urlString string, action git2go.SmartServi
}

func (t *sshSmartSubtransport) Close() error {
var returnErr error
t.currentStream = nil
if t.client != nil {
t.stdin.Close()
t.session.Wait()
t.session.Close()
if err := t.stdin.Close(); err != nil {
returnErr = fmt.Errorf("cannot close stdin: %w", err)
}
t.client = nil
}
return nil
if t.session != nil {

// In some scenarios session.Wait() can hang indefinitely.
// Here we force a timeout to skip the wait and continue
// with closing the session.
done := make(chan error, 1)
go func() {
err := t.session.Wait()
done <- err
}()

select {
case doneErr := <-done:
if doneErr != nil {
returnErr = fmt.Errorf("cannot wait session: %w", doneErr)
}
case <-time.After(5 * time.Second):
returnErr = fmt.Errorf("timed out waiting for session.Wait()")
}

if err := t.session.Close(); err != nil {
returnErr = fmt.Errorf("cannot close session: %w", err)
}
}

return returnErr
}

func (t *sshSmartSubtransport) Free() {
Expand Down

0 comments on commit c2b58f0

Please sign in to comment.