Skip to content

Commit a5de8c6

Browse files
committed
perf: adjust read/write timeouts for redir
1 parent 6f8c486 commit a5de8c6

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

pkg/wsman/client/wsman.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ type Target struct {
6868
UseTLS bool
6969
InsecureSkipVerify bool
7070
PinnedCert string
71-
tlsConfig *tls.Config
71+
tlsConfig *tls.Config
72+
lastReadDeadlineSet time.Time // Track when read deadline was last set
73+
lastWriteDeadlineSet time.Time // Track when write deadline was last set
74+
deadlineMutex sync.Mutex // Protect deadline setting operations
7275
}
7376

7477
const timeout = 10 * time.Second

pkg/wsman/client/wsman_tcp.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ const (
2121

2222
// defaultKeepAlive configures TCP keepalive probe interval on the dialer.
2323
defaultKeepAlive = 30 * time.Second
24+
25+
// defaultReadTimeout sets the maximum time to wait for read operations.
26+
defaultReadTimeout = 30 * time.Second
27+
28+
// defaultWriteTimeout sets the maximum time to wait for write operations.
29+
defaultWriteTimeout = 30 * time.Second
2430
)
2531

2632
func NewWsmanTCP(cp Parameters) *Target {
@@ -127,6 +133,11 @@ func (t *Target) Send(data []byte) error {
127133
return fmt.Errorf("no active connection")
128134
}
129135

136+
// Optimize: Only set deadline if enough time has passed or it's not set
137+
if err := t.setWriteDeadlineIfNeeded(); err != nil {
138+
return fmt.Errorf("failed to set write deadline: %w", err)
139+
}
140+
130141
_, err := t.conn.Write(data)
131142
if err != nil {
132143
return fmt.Errorf("failed to send data: %w", err)
@@ -141,6 +152,11 @@ func (t *Target) Receive() ([]byte, error) {
141152
return nil, fmt.Errorf("no active connection")
142153
}
143154

155+
// Optimize: Only set deadline if enough time has passed or it's not set
156+
if err := t.setReadDeadlineIfNeeded(); err != nil {
157+
return nil, fmt.Errorf("failed to set read deadline: %w", err)
158+
}
159+
144160
tmp := t.bufferPool.Get().([]byte)
145161
defer t.bufferPool.Put(tmp) //nolint:staticcheck // changing the argument to be pointer-like to avoid allocations caused issues.
146162

@@ -152,6 +168,48 @@ func (t *Target) Receive() ([]byte, error) {
152168
return append([]byte(nil), tmp[:n]...), nil
153169
}
154170

171+
// setReadDeadlineIfNeeded sets read deadline only when needed to reduce syscall overhead
172+
func (t *Target) setReadDeadlineIfNeeded() error {
173+
t.deadlineMutex.Lock()
174+
defer t.deadlineMutex.Unlock()
175+
176+
now := time.Now()
177+
// Only set deadline if it's been more than half the timeout period since last set
178+
// or if it's never been set (zero value)
179+
const deadlineRefreshInterval = defaultReadTimeout / 2
180+
181+
if t.lastReadDeadlineSet.IsZero() || now.Sub(t.lastReadDeadlineSet) > deadlineRefreshInterval {
182+
newDeadline := now.Add(defaultReadTimeout)
183+
if err := t.conn.SetReadDeadline(newDeadline); err != nil {
184+
return err
185+
}
186+
t.lastReadDeadlineSet = now
187+
}
188+
189+
return nil
190+
}
191+
192+
// setWriteDeadlineIfNeeded sets write deadline only when needed to reduce syscall overhead
193+
func (t *Target) setWriteDeadlineIfNeeded() error {
194+
t.deadlineMutex.Lock()
195+
defer t.deadlineMutex.Unlock()
196+
197+
now := time.Now()
198+
// Only set deadline if it's been more than half the timeout period since last set
199+
// or if it's never been set (zero value)
200+
const deadlineRefreshInterval = defaultWriteTimeout / 2
201+
202+
if t.lastWriteDeadlineSet.IsZero() || now.Sub(t.lastWriteDeadlineSet) > deadlineRefreshInterval {
203+
newDeadline := now.Add(defaultWriteTimeout)
204+
if err := t.conn.SetWriteDeadline(newDeadline); err != nil {
205+
return err
206+
}
207+
t.lastWriteDeadlineSet = now
208+
}
209+
210+
return nil
211+
}
212+
155213
// CloseConnection cleanly closes the TCP connection.
156214
func (t *Target) CloseConnection() error {
157215
if t.conn == nil {
@@ -164,6 +222,12 @@ func (t *Target) CloseConnection() error {
164222
}
165223

166224
t.conn = nil
225+
226+
// Reset deadline tracking when connection is closed
227+
t.deadlineMutex.Lock()
228+
t.lastReadDeadlineSet = time.Time{}
229+
t.lastWriteDeadlineSet = time.Time{}
230+
t.deadlineMutex.Unlock()
167231

168232
return nil
169233
}

0 commit comments

Comments
 (0)