Make ckpool client resilient to warm-up EOFs
The stratifier can accept a connection and close it without writing a response during early startup — the refresh loop then logs 'ckpool poolstats failed: read len: EOF' on every tick until the stratifier is ready, which is noisy and looks like a real fault. - client.Send retries once after 200ms if the server closed the connection before any bytes were read (io.EOF anywhere in the wrapped chain). - Aggregator tracks a ckFailStreak counter: first two consecutive failures log at DEBUG, third and beyond escalate to WARN. Successful refreshes reset the streak.
This commit is contained in:
@@ -51,7 +51,24 @@ var ErrProtocol = errors.New("ckpool: protocol error")
|
||||
// Send delivers a single command to the named ckpool socket and returns the
|
||||
// raw response bytes. `sockName` is one of SocketListener, SocketStratifier,
|
||||
// or SocketConnector.
|
||||
//
|
||||
// If the server closes the connection before writing a response (common
|
||||
// during ckpool warm-up — the stratifier accepts the socket but its stats
|
||||
// aren't populated yet), Send retries once after a short backoff.
|
||||
func (c *Client) Send(ctx context.Context, sockName, cmd string) ([]byte, error) {
|
||||
buf, err := c.sendOnce(ctx, sockName, cmd)
|
||||
if err != nil && errors.Is(err, io.EOF) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-time.After(200 * time.Millisecond):
|
||||
}
|
||||
return c.sendOnce(ctx, sockName, cmd)
|
||||
}
|
||||
return buf, err
|
||||
}
|
||||
|
||||
func (c *Client) sendOnce(ctx context.Context, sockName, cmd string) ([]byte, error) {
|
||||
if cmd == "" {
|
||||
return nil, fmt.Errorf("ckpool: empty command")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user