Skip to content

Commit 0ebeaf9

Browse files
authored
Merge pull request #130 from RLBot/bound-chan
Fix memory leak
2 parents b0cccb4 + 9253c3b commit 0ebeaf9

File tree

5 files changed

+40
-17
lines changed

5 files changed

+40
-17
lines changed

RLBotCS/Server/FlatBuffersServer.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ChannelWriter<IBridgeMessage> bridge
2020

2121
private void AddSession(TcpClient client)
2222
{
23-
Channel<SessionMessage> sessionChannel = Channel.CreateUnbounded<SessionMessage>();
23+
Channel<SessionMessage> sessionChannel = Channel.CreateBounded<SessionMessage>(60);
2424
client.NoDelay = true;
2525

2626
int clientId = client.Client.Handle.ToInt32();
@@ -96,7 +96,11 @@ private async Task HandleServer()
9696
while (true)
9797
{
9898
TcpClient client = await _context.Server.AcceptTcpClientAsync();
99-
AddSession(client);
99+
100+
lock (_context)
101+
{
102+
AddSession(client);
103+
}
100104
}
101105
}
102106
catch (Exception e)

RLBotCS/Server/ServerMessage/DistributeGamePacket.cs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using RLBot.Flat;
1+
using RLBot.Flat;
22
using RLBotCS.ManagerTools;
33

44
namespace RLBotCS.Server.ServerMessage;
@@ -28,24 +28,15 @@ private static void DistributeBallPrediction(ServerContext context, GamePacketT
2828
lastTouch,
2929
packet.MatchInfo.WorldGravityZ
3030
);
31-
32-
foreach (var (writer, _) in context.Sessions.Values)
33-
{
34-
SessionMessage message = new SessionMessage.DistributeBallPrediction(prediction);
35-
writer.TryWrite(message);
36-
}
31+
context.DistributeMessage(new SessionMessage.DistributeBallPrediction(prediction));
3732
}
3833

3934
private static void DistributeState(ServerContext context, GamePacketT packet)
4035
{
4136
context.LastTickPacket = packet;
42-
foreach (var (writer, _) in context.Sessions.Values)
43-
{
44-
SessionMessage message = new SessionMessage.DistributeGameState(
45-
context.LastTickPacket
46-
);
47-
writer.TryWrite(message);
48-
}
37+
context.DistributeMessage(
38+
new SessionMessage.DistributeGameState(context.LastTickPacket)
39+
);
4940
}
5041

5142
public ServerAction Execute(ServerContext context)

RLBotCS/Server/ServerMessage/SendMatchComm.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public ServerAction Execute(ServerContext context)
1111

1212
if (context.LastTickPacket is null)
1313
{
14-
context.Logger.LogWarning("Received MatchComm before receiving a GameTickPacket.");
14+
context.Logger.LogWarning("Received MatchComm before receiving a GamePacket.");
1515
return ServerAction.Continue;
1616
}
1717

RLBotCS/Server/ServerMessage/ServerContext.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,31 @@ public Dictionary<
4646
/// The BridgeHandler's config may contain updated names, e.g. "Nexto (2)",
4747
/// and updated loadouts.</summary>
4848
public MatchConfigurationT? MatchConfig { get; set; }
49+
50+
public readonly Dictionary<int, uint> MissedMessagesCount = new();
51+
52+
public void DistributeMessage(SessionMessage message)
53+
{
54+
foreach (var (id, (writer, _)) in Sessions)
55+
{
56+
if (!writer.TryWrite(message))
57+
{
58+
uint missedMessages = MissedMessagesCount.GetValueOrDefault(id) + 1;
59+
MissedMessagesCount[id] = missedMessages;
60+
61+
// Log warning with exponential backoff,
62+
// e.g. every 10, 100, 1000, etc. messages missed
63+
// (including the first missed message)
64+
uint powerOfTen = (uint)Math.Pow(10, Math.Ceiling(Math.Log10(missedMessages)));
65+
if (missedMessages == powerOfTen)
66+
{
67+
Logger.LogWarning(
68+
"Session {}'s outbound message queue is full ({} messages missed)",
69+
id,
70+
missedMessages
71+
);
72+
}
73+
}
74+
}
75+
}
4976
}

RLBotCS/Server/ServerMessage/SessionClosed.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public ServerAction Execute(ServerContext context)
88
{
99
context.Bridge.TryWrite(new RemoveClientRenders(ClientId));
1010
context.Sessions.Remove(ClientId);
11+
context.MissedMessagesCount.Remove(ClientId);
1112

1213
return ServerAction.Continue;
1314
}

0 commit comments

Comments
 (0)