Remove timeout conn on net.Dialer (#7590)

This PR also removes conn_bug_21133 workaround
which is not valid anymore, all we need is deadline
connection with server in place

Fixes #7503
master
Harshavardhana 6 years ago committed by GitHub
parent b93ef73f9b
commit af6c6a2b35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 48
      cmd/http/conn_bug_21133.go
  2. 6
      cmd/http/deadlineconn.go
  3. 62
      cmd/http/timeoutconn.go
  4. 7
      cmd/rest/client.go

@ -1,48 +0,0 @@
/*
* MinIO Cloud Storage, (C) 2017 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package http
import (
"net"
"sync/atomic"
"time"
)
// QuirkConn - similar to golang net.Conn struct, but contains a workaround of the
// following the go bug reported here https://github.com/golang/go/issues/21133.
// Once the bug will be fixed, we can remove this structure and replaces it with
// the standard net.Conn
type QuirkConn struct {
net.Conn
hadReadDeadlineInPast int32 // atomic
}
// SetReadDeadline - implements a workaround of SetReadDeadline go bug
func (q *QuirkConn) SetReadDeadline(t time.Time) error {
inPast := int32(0)
if t.Before(time.Now()) {
inPast = 1
}
atomic.StoreInt32(&q.hadReadDeadlineInPast, inPast)
return q.Conn.SetReadDeadline(t)
}
// canSetReadDeadline - returns if it is safe to set a new
// read deadline without triggering golang/go#21133 issue.
func (q *QuirkConn) canSetReadDeadline() bool {
return atomic.LoadInt32(&q.hadReadDeadlineInPast) != 1
}

@ -23,7 +23,7 @@ import (
// DeadlineConn - is a generic stream-oriented network connection supporting buffered reader and read/write timeout.
type DeadlineConn struct {
QuirkConn
net.Conn
readTimeout time.Duration // sets the read timeout in the connection.
writeTimeout time.Duration // sets the write timeout in the connection.
updateBytesReadFunc func(int) // function to be called to update bytes read.
@ -32,7 +32,7 @@ type DeadlineConn struct {
// Sets read timeout
func (c *DeadlineConn) setReadTimeout() {
if c.readTimeout != 0 && c.canSetReadDeadline() {
if c.readTimeout != 0 {
c.SetReadDeadline(time.Now().UTC().Add(c.readTimeout))
}
}
@ -68,7 +68,7 @@ func (c *DeadlineConn) Write(b []byte) (n int, err error) {
// newDeadlineConn - creates a new connection object wrapping net.Conn with deadlines.
func newDeadlineConn(c net.Conn, readTimeout, writeTimeout time.Duration, updateBytesReadFunc, updateBytesWrittenFunc func(int)) *DeadlineConn {
return &DeadlineConn{
QuirkConn: QuirkConn{Conn: c},
Conn: c,
readTimeout: readTimeout,
writeTimeout: writeTimeout,
updateBytesReadFunc: updateBytesReadFunc,

@ -1,62 +0,0 @@
/*
* MinIO Cloud Storage, (C) 2018 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package http
import (
"net"
"time"
)
// TimeoutConn - is wrapped net.Conn with read/write timeouts.
type TimeoutConn struct {
QuirkConn
readTimeout time.Duration
writeTimeout time.Duration
}
func (c *TimeoutConn) setReadTimeout() {
if c.readTimeout != 0 && c.canSetReadDeadline() {
c.SetReadDeadline(time.Now().UTC().Add(c.readTimeout))
}
}
func (c *TimeoutConn) setWriteTimeout() {
if c.writeTimeout != 0 {
c.SetWriteDeadline(time.Now().UTC().Add(c.writeTimeout))
}
}
// Read - reads data from the connection with timeout.
func (c *TimeoutConn) Read(b []byte) (n int, err error) {
c.setReadTimeout()
return c.Conn.Read(b)
}
// Write - writes data to the connection with timeout.
func (c *TimeoutConn) Write(b []byte) (n int, err error) {
c.setWriteTimeout()
return c.Conn.Write(b)
}
// NewTimeoutConn - creates a new timeout connection.
func NewTimeoutConn(c net.Conn, readTimeout, writeTimeout time.Duration) *TimeoutConn {
return &TimeoutConn{
QuirkConn: QuirkConn{Conn: c},
readTimeout: readTimeout,
writeTimeout: writeTimeout,
}
}

@ -89,12 +89,7 @@ func newCustomDialContext(timeout time.Duration) func(ctx context.Context, netwo
DualStack: true,
}
conn, err := dialer.DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
return xhttp.NewTimeoutConn(conn, timeout, timeout), nil
return dialer.DialContext(ctx, network, addr)
}
}

Loading…
Cancel
Save