Skip to content

Commit 0132bac

Browse files
committed
refactor: use retry library
1 parent 18f8aaa commit 0132bac

File tree

3 files changed

+61
-90
lines changed

3 files changed

+61
-90
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ require (
5050
github.com/prometheus/client_model v0.6.1 // indirect
5151
github.com/prometheus/common v0.62.0 // indirect
5252
github.com/prometheus/procfs v0.15.1 // indirect
53+
github.com/sethvargo/go-retry v0.3.0 // indirect
5354
github.com/x448/float16 v0.8.4 // indirect
5455
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
5556
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg
160160
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
161161
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
162162
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
163+
github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE=
164+
github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas=
163165
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
164166
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
165167
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=

server/connector.go

Lines changed: 58 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ import (
2121
"github.com/juju/ratelimit"
2222
"github.com/pires/go-proxyproto"
2323
"github.com/sirupsen/logrus"
24+
"github.com/sethvargo/go-retry"
2425
)
2526

2627
const (
2728
handshakeTimeout = 5 * time.Second
2829
backendTimeout = 30 * time.Second
29-
backendRetryInterval = 5 * time.Second
30+
backendRetryInterval = 3 * time.Second
3031
backendStatusTimeout = 1 * time.Second
3132
)
3233

@@ -485,110 +486,77 @@ func (c *Connector) findAndConnectBackend(ctx context.Context, frontendConn net.
485486
WithField("player", playerInfo).
486487
Info("Connecting to backend")
487488

488-
var backendConn net.Conn
489-
var err error
490-
491-
if nextState == mcproto.StateStatus {
492-
// Status request: try to connect once with backendStatusTimeout
493-
backendConn, err = net.DialTimeout("tcp", backendHostPort, backendStatusTimeout)
494-
if err != nil {
489+
// We want to try to connect to the backend every backendRetryInterval
490+
var backendTry retry.Backoff
491+
492+
switch nextState {
493+
case mcproto.StateStatus:
494+
// Status request: try to connect once with backendStatusTimeout
495+
backendTry = retry.NewConstant(backendStatusTimeout)
496+
backendTry = retry.WithMaxRetries(0, backendTry)
497+
case mcproto.StateLogin:
498+
backendTry = retry.NewConstant(backendRetryInterval)
499+
// Connect request: if autoscaler is enabled, try to connect until backendTimeout is reached
500+
if waker != nil {
501+
// Autoscaler enabled: retry until backendTimeout is reached
502+
backendTry = retry.WithMaxDuration(backendTimeout, backendTry)
503+
} else {
504+
// Autoscaler disabled: try to connect once with backendRetryInterval
505+
backendTry = retry.WithMaxRetries(0, backendTry)
506+
}
507+
default:
508+
// Unknown state, do nothing
495509
logrus.
496-
WithError(err).
497510
WithField("client", clientAddr).
498511
WithField("serverAddress", serverAddress).
499-
WithField("backend", backendHostPort).
512+
WithField("nextState", nextState).
500513
WithField("player", playerInfo).
501-
Warn("Unable to connect to backend for status request")
502-
c.metrics.Errors.With("type", "backend_failed").Add(1)
514+
Error("Unknown state, unable to connect to backend")
515+
return
516+
}
503517

504-
if c.connectionNotifier != nil {
505-
notifyErr := c.connectionNotifier.NotifyFailedBackendConnection(ctx, clientAddr, serverAddress, playerInfo, backendHostPort, err)
506-
if notifyErr != nil {
507-
logrus.WithError(notifyErr).Warn("failed to notify failed backend connection")
508-
}
509-
}
518+
var backendConn net.Conn
519+
if retryErr := retry.Do(ctx, backendTry, func(ctx context.Context) error {
520+
logrus.Debug("Attempting to connect")
521+
var err error
522+
backendConn, err = net.Dial("tcp", backendHostPort)
523+
if err != nil { return retry.RetryableError(err) }
524+
return nil
525+
}); retryErr != nil {
526+
logrus.
527+
WithError(retryErr).
528+
WithField("client", clientAddr).
529+
WithField("serverAddress", serverAddress).
530+
WithField("backend", backendHostPort).
531+
WithField("player", playerInfo).
532+
Warn("Unable to connect to backend")
533+
c.metrics.Errors.With("type", "backend_failed").Add(1)
510534

511-
// Return fakeOnline MOTD
512-
if c.fakeOnline && waker != nil {
513-
logrus.Info("Server is offline, sending fakeOnlineMOTD for status request")
514-
writeStatusErr := mcproto.WriteStatusResponse(
515-
frontendConn,
516-
c.fakeOnlineMOTD,
517-
)
518-
if writeStatusErr != nil {
519-
logrus.
520-
WithError(writeStatusErr).
521-
WithField("client", clientAddr).
522-
WithField("serverAddress", serverAddress).
523-
WithField("backend", backendHostPort).
524-
WithField("player", playerInfo).
525-
Error("Failed to write status response")
526-
}
535+
if c.connectionNotifier != nil {
536+
notifyErr := c.connectionNotifier.NotifyFailedBackendConnection(ctx, clientAddr, serverAddress, playerInfo, backendHostPort, retryErr)
537+
if notifyErr != nil {
538+
logrus.WithError(notifyErr).Warn("failed to notify failed backend connection")
527539
}
528-
return
529540
}
530-
} else if nextState == mcproto.StateLogin {
531-
// Connect request
532-
if waker != nil {
533-
logrus.Debug("Connect: Autoscaler is enabled, waiting for backend to be ready")
534-
// Autoscaler enabled: retry until backendTimeout is reached
535-
deadline := time.Now().Add(backendTimeout)
536-
for {
537-
backendConn, err = net.DialTimeout("tcp", backendHostPort, backendRetryInterval)
538-
logrus.Debug("Tries to connect to backend")
539-
540-
if err == nil {
541-
break
542-
}
543-
if time.Now().After(deadline) {
544-
logrus.
545-
WithError(err).
546-
WithField("client", clientAddr).
547-
WithField("serverAddress", serverAddress).
548-
WithField("backend", backendHostPort).
549-
WithField("player", playerInfo).
550-
Warn("Unable to connect to backend after retries (autoscaler enabled)")
551-
c.metrics.Errors.With("type", "backend_failed").Add(1)
552-
if c.connectionNotifier != nil {
553-
notifyErr := c.connectionNotifier.NotifyFailedBackendConnection(ctx, clientAddr, serverAddress, playerInfo, backendHostPort, err)
554-
if notifyErr != nil {
555-
logrus.WithError(notifyErr).Warn("failed to notify failed backend connection")
556-
}
557-
}
558-
return
559-
}
560-
time.Sleep(backendRetryInterval)
561-
}
562-
} else {
563-
logrus.Debug("Connect: Autoscaler is disabled, trying to connect once")
564-
// Autoscaler disabled: try to connect once with backendTimeout
565-
backendConn, err = net.DialTimeout("tcp", backendHostPort, backendTimeout)
566-
if err != nil {
541+
542+
if nextState == mcproto.StateStatus && c.fakeOnline && waker != nil {
543+
logrus.Info("Server is offline, sending fakeOnlineMOTD for status request")
544+
writeStatusErr := mcproto.WriteStatusResponse(
545+
frontendConn,
546+
c.fakeOnlineMOTD,
547+
)
548+
549+
if writeStatusErr != nil {
567550
logrus.
568-
WithError(err).
551+
WithError(writeStatusErr).
569552
WithField("client", clientAddr).
570553
WithField("serverAddress", serverAddress).
571554
WithField("backend", backendHostPort).
572555
WithField("player", playerInfo).
573-
Warn("Unable to connect to backend (autoscaler disabled)")
574-
c.metrics.Errors.With("type", "backend_failed").Add(1)
575-
if c.connectionNotifier != nil {
576-
notifyErr := c.connectionNotifier.NotifyFailedBackendConnection(ctx, clientAddr, serverAddress, playerInfo, backendHostPort, err)
577-
if notifyErr != nil {
578-
logrus.WithError(notifyErr).Warn("failed to notify failed backend connection")
579-
}
580-
}
581-
return
556+
Error("Failed to write status response")
582557
}
583558
}
584-
} else {
585-
// Unknown state, do nothing
586-
logrus.
587-
WithField("client", clientAddr).
588-
WithField("serverAddress", serverAddress).
589-
WithField("nextState", nextState).
590-
WithField("player", playerInfo).
591-
Warn("Unknown state, unable to connect to backend")
559+
592560
return
593561
}
594562

0 commit comments

Comments
 (0)