Skip to content

Commit c77b24e

Browse files
committed
add buffer limit
1 parent 4166c29 commit c77b24e

File tree

1 file changed

+45
-14
lines changed

1 file changed

+45
-14
lines changed

agent/agent.go

+45-14
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,17 @@ func (a *agent) reportConnectionsLoop(ctx context.Context, aAPI proto.DRPCAgentC
781781
}
782782
}
783783

784+
const (
785+
// reportConnectionBufferLimit limits the number of connection reports we
786+
// buffer to avoid growing the buffer indefinitely. This should not happen
787+
// unless the agent has lost connection to coderd for a long time or if
788+
// the agent is being spammed with connections.
789+
//
790+
// If we assume ~150 byte per connection report, this would be around 300KB
791+
// of memory which seems acceptable.
792+
reportConnectionBufferLimit = 2048
793+
)
794+
784795
func (a *agent) reportConnection(id uuid.UUID, connectionType proto.Connection_Type, ip string) (disconnected func(code int, reason string)) {
785796
// If the experiment hasn't been enabled, we don't report connections.
786797
if !a.experimentalConnectionReports {
@@ -797,25 +808,45 @@ func (a *agent) reportConnection(id uuid.UUID, connectionType proto.Connection_T
797808

798809
a.reportConnectionsMu.Lock()
799810
defer a.reportConnectionsMu.Unlock()
800-
a.reportConnections = append(a.reportConnections, &proto.ReportConnectionRequest{
801-
Connection: &proto.Connection{
802-
Id: id[:],
803-
Action: proto.Connection_CONNECT,
804-
Type: connectionType,
805-
Timestamp: timestamppb.New(time.Now()),
806-
Ip: ip,
807-
StatusCode: 0,
808-
Reason: nil,
809-
},
810-
})
811-
select {
812-
case a.reportConnectionsUpdate <- struct{}{}:
813-
default:
811+
812+
if len(a.reportConnections) >= reportConnectionBufferLimit {
813+
a.logger.Warn(a.hardCtx, "connection report buffer limit reached, dropping connect",
814+
slog.F("limit", reportConnectionBufferLimit),
815+
slog.F("connection_id", id),
816+
slog.F("connection_type", connectionType),
817+
slog.F("ip", ip),
818+
)
819+
} else {
820+
a.reportConnections = append(a.reportConnections, &proto.ReportConnectionRequest{
821+
Connection: &proto.Connection{
822+
Id: id[:],
823+
Action: proto.Connection_CONNECT,
824+
Type: connectionType,
825+
Timestamp: timestamppb.New(time.Now()),
826+
Ip: ip,
827+
StatusCode: 0,
828+
Reason: nil,
829+
},
830+
})
831+
select {
832+
case a.reportConnectionsUpdate <- struct{}{}:
833+
default:
834+
}
814835
}
815836

816837
return func(code int, reason string) {
817838
a.reportConnectionsMu.Lock()
818839
defer a.reportConnectionsMu.Unlock()
840+
if len(a.reportConnections) >= reportConnectionBufferLimit {
841+
a.logger.Warn(a.hardCtx, "connection report buffer limit reached, dropping connect",
842+
slog.F("limit", reportConnectionBufferLimit),
843+
slog.F("connection_id", id),
844+
slog.F("connection_type", connectionType),
845+
slog.F("ip", ip),
846+
)
847+
return
848+
}
849+
819850
a.reportConnections = append(a.reportConnections, &proto.ReportConnectionRequest{
820851
Connection: &proto.Connection{
821852
Id: id[:],

0 commit comments

Comments
 (0)