mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-08 05:57:03 +09:00
52 lines
1.4 KiB
Go
52 lines
1.4 KiB
Go
package connutil
|
|
|
|
import (
|
|
"errors"
|
|
"net"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/anyproto/any-sync/app/logger"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var log = logger.NewNamed("common.net.connutil")
|
|
|
|
type TimeoutConn struct {
|
|
net.Conn
|
|
timeout time.Duration
|
|
}
|
|
|
|
func NewTimeout(conn net.Conn, timeout time.Duration) *TimeoutConn {
|
|
return &TimeoutConn{conn, timeout}
|
|
}
|
|
|
|
func (c *TimeoutConn) Write(p []byte) (n int, err error) {
|
|
for {
|
|
if c.timeout != 0 {
|
|
if e := c.Conn.SetWriteDeadline(time.Now().Add(c.timeout)); e != nil {
|
|
log.Warn("can't set write deadline", zap.String("remoteAddr", c.RemoteAddr().String()))
|
|
}
|
|
}
|
|
nn, err := c.Conn.Write(p[n:])
|
|
n += nn
|
|
if n < len(p) && nn > 0 && errors.Is(err, os.ErrDeadlineExceeded) {
|
|
// Keep extending the deadline so long as we're making progress.
|
|
log.Debug("keep extending the deadline so long as we're making progress", zap.String("remoteAddr", c.RemoteAddr().String()))
|
|
continue
|
|
}
|
|
if c.timeout != 0 {
|
|
if e := c.Conn.SetWriteDeadline(time.Time{}); e != nil {
|
|
log.Warn("can't set write deadline", zap.String("remoteAddr", c.RemoteAddr().String()))
|
|
}
|
|
}
|
|
if err != nil {
|
|
// if the connection is timed out and we should close it
|
|
if e := c.Conn.Close(); e != nil {
|
|
log.Warn("connection close error", zap.String("remoteAddr", c.RemoteAddr().String()))
|
|
}
|
|
log.Debug("connection timed out", zap.String("remoteAddr", c.RemoteAddr().String()))
|
|
}
|
|
return n, err
|
|
}
|
|
}
|