Browse Source

debug: introduce support for configuring client connect WRITE deadline (#19170)

just like client-conn-read-deadline, added a new flag that does
client-conn-write-deadline as well.

Both are not configured by default, since we do not yet know
what is the right value. Allow this to be configurable if needed.
pull/19173/head
Harshavardhana 1 year ago
committed by GitHub
parent
commit
2c2f5d871c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      cmd/common-main.go
  2. 9
      cmd/globals.go
  3. 16
      cmd/handler-utils.go
  4. 13
      cmd/server-main.go
  5. 18
      internal/cachevalue/cache.go
  6. 12
      internal/http/listener.go

1
cmd/common-main.go

@ -393,6 +393,7 @@ func buildServerCtxt(ctx *cli.Context, ctxt *serverCtxt) (err error) {
ctxt.ConnReadDeadline = ctx.Duration("conn-read-deadline")
ctxt.ConnWriteDeadline = ctx.Duration("conn-write-deadline")
ctxt.ConnClientReadDeadline = ctx.Duration("conn-client-read-deadline")
ctxt.ConnClientWriteDeadline = ctx.Duration("conn-client-write-deadline")
ctxt.ShutdownTimeout = ctx.Duration("shutdown-timeout")
ctxt.IdleTimeout = ctx.Duration("idle-timeout")

9
cmd/globals.go

@ -160,10 +160,11 @@ type serverCtxt struct {
FTP []string
SFTP []string
UserTimeout time.Duration
ConnReadDeadline time.Duration
ConnWriteDeadline time.Duration
ConnClientReadDeadline time.Duration
UserTimeout time.Duration
ConnReadDeadline time.Duration
ConnWriteDeadline time.Duration
ConnClientReadDeadline time.Duration
ConnClientWriteDeadline time.Duration
ShutdownTimeout time.Duration
IdleTimeout time.Duration

16
cmd/handler-utils.go

@ -296,27 +296,23 @@ func collectAPIStats(api string, f http.HandlerFunc) http.HandlerFunc {
bucket, _ := path2BucketObject(resource)
globalHTTPStats.currentS3Requests.Inc(api)
defer globalHTTPStats.currentS3Requests.Dec(api)
_, err = globalBucketMetadataSys.Get(bucket) // check if this bucket exists.
if bucket != "" && bucket != minioReservedBucket && err == nil {
countBktStat := bucket != "" && bucket != minioReservedBucket && err == nil
if countBktStat {
globalBucketHTTPStats.updateHTTPStats(bucket, api, nil)
}
globalHTTPStats.currentS3Requests.Inc(api)
f.ServeHTTP(w, r)
globalHTTPStats.currentS3Requests.Dec(api)
tc, ok := r.Context().Value(mcontext.ContextTraceKey).(*mcontext.TraceCtxt)
if !ok {
return
}
tc, _ := r.Context().Value(mcontext.ContextTraceKey).(*mcontext.TraceCtxt)
if tc != nil {
globalHTTPStats.updateStats(api, tc.ResponseRecorder)
globalConnStats.incS3InputBytes(int64(tc.RequestRecorder.Size()))
globalConnStats.incS3OutputBytes(int64(tc.ResponseRecorder.Size()))
if bucket != "" && bucket != minioReservedBucket && err == nil {
if countBktStat {
globalBucketConnStats.incS3InputBytes(bucket, int64(tc.RequestRecorder.Size()))
globalBucketConnStats.incS3OutputBytes(bucket, int64(tc.ResponseRecorder.Size()))
globalBucketHTTPStats.updateHTTPStats(bucket, api, tc.ResponseRecorder)

13
cmd/server-main.go

@ -106,6 +106,12 @@ var ServerFlags = []cli.Flag{
Hidden: true,
EnvVar: "MINIO_CONN_CLIENT_READ_DEADLINE",
},
cli.DurationFlag{
Name: "conn-client-write-deadline",
Usage: "custom connection WRITE deadline for outgoing requests",
Hidden: true,
EnvVar: "MINIO_CONN_CLIENT_WRITE_DEADLINE",
},
cli.DurationFlag{
Name: "conn-read-deadline",
Usage: "custom connection READ deadline",
@ -356,9 +362,10 @@ func serverHandleCmdArgs(ctxt serverCtxt) {
})
globalTCPOptions = xhttp.TCPOptions{
UserTimeout: int(ctxt.UserTimeout.Milliseconds()),
ClientReadTimeout: ctxt.ConnClientReadDeadline,
Interface: ctxt.Interface,
UserTimeout: int(ctxt.UserTimeout.Milliseconds()),
ClientReadTimeout: ctxt.ConnClientReadDeadline,
ClientWriteTimeout: ctxt.ConnClientWriteDeadline,
Interface: ctxt.Interface,
}
// On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back

18
internal/cachevalue/cache.go

@ -70,16 +70,16 @@ type Cache[T any] struct {
updating sync.Mutex
}
// New allocates a new cached value instance. It must be initialized with
// `.InitOnce`.
func New[I any]() *Cache[I] {
return &Cache[I]{}
// New allocates a new cached value instance. Tt must be initialized with
// `.TnitOnce`.
func New[T any]() *Cache[T] {
return &Cache[T]{}
}
// NewFromFunc allocates a new cached value instance and initializes it with an
// update function, making it ready for use.
func NewFromFunc[I any](ttl time.Duration, opts Opts, update func() (I, error)) *Cache[I] {
return &Cache[I]{
func NewFromFunc[T any](ttl time.Duration, opts Opts, update func() (T, error)) *Cache[T] {
return &Cache[T]{
ttl: ttl,
updateFn: update,
opts: opts,
@ -88,7 +88,7 @@ func NewFromFunc[I any](ttl time.Duration, opts Opts, update func() (I, error))
// InitOnce initializes the cache with a TTL and an update function. It is
// guaranteed to be called only once.
func (t *Cache[I]) InitOnce(ttl time.Duration, opts Opts, update func() (I, error)) {
func (t *Cache[T]) InitOnce(ttl time.Duration, opts Opts, update func() (T, error)) {
t.Once.Do(func() {
t.ttl = ttl
t.updateFn = update
@ -97,8 +97,8 @@ func (t *Cache[I]) InitOnce(ttl time.Duration, opts Opts, update func() (I, erro
}
// Get will return a cached value or fetch a new one.
// If the Update function returns an error the value is forwarded as is and not cached.
func (t *Cache[I]) Get() (I, error) {
// Tf the Update function returns an error the value is forwarded as is and not cached.
func (t *Cache[T]) Get() (T, error) {
v := t.valErr.Load()
ttl := t.ttl
vTime := t.lastUpdateMs.Load()

12
internal/http/listener.go

@ -79,7 +79,8 @@ func (listener *httpListener) Accept() (conn net.Conn, err error) {
case result, ok := <-listener.acceptCh:
if ok {
return deadlineconn.New(result.conn).
WithReadDeadline(listener.opts.ClientReadTimeout), result.err
WithReadDeadline(listener.opts.ClientReadTimeout).
WithWriteDeadline(listener.opts.ClientWriteTimeout), result.err
}
case <-listener.ctx.Done():
}
@ -124,10 +125,11 @@ func (listener *httpListener) Addrs() (addrs []net.Addr) {
// TCPOptions specify customizable TCP optimizations on raw socket
type TCPOptions struct {
UserTimeout int // this value is expected to be in milliseconds
ClientReadTimeout time.Duration // When the net.Conn is idle for more than ReadTimeout duration, we close the connection on the client proactively.
Interface string // this is a VRF device passed via `--interface` flag
Trace func(msg string) // Trace when starting.
UserTimeout int // this value is expected to be in milliseconds
ClientReadTimeout time.Duration // When the net.Conn is idle for more than ReadTimeout duration, we close the connection on the client proactively.
ClientWriteTimeout time.Duration // When the net.Conn is idle for more than WriteTimeout duration, we close the connection on the client proactively.
Interface string // this is a VRF device passed via `--interface` flag
Trace func(msg string) // Trace when starting.
}
// newHTTPListener - creates new httpListener object which is interface compatible to net.Listener.

Loading…
Cancel
Save