Run ProcessQueuedAcks asynchronously (#4696)

This commit is contained in:
metalgearsloth
2023-12-16 05:10:09 +11:00
committed by GitHub
parent 2686150f9d
commit 8d30735ffb
3 changed files with 14 additions and 8 deletions

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Threading;
using Robust.Shared.GameObjects;
using Robust.Shared.Player;
using Robust.Shared.Threading;
@@ -29,10 +30,12 @@ internal sealed partial class PvsSystem
/// <summary>
/// Processes queued client acks in parallel
/// </summary>
internal void ProcessQueuedAcks()
internal WaitHandle ProcessQueuedAcks()
{
if (PendingAcks.Count == 0)
return;
{
return ParallelManager.DummyResetEvent.WaitHandle;
}
_toAck.Clear();
@@ -41,8 +44,8 @@ internal sealed partial class PvsSystem
_toAck.Add(session);
}
_parallelManager.ProcessNow(_ackJob, _toAck.Count);
PendingAcks.Clear();
return _parallelManager.Process(_ackJob, _toAck.Count);
}
private record struct PvsAckJob : IParallelRobustJob

View File

@@ -3,6 +3,7 @@ using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Robust.Server.GameObjects;
@@ -173,6 +174,10 @@ Oldest acked clients: {string.Join(", ", players)}
{
var players = _playerManager.Sessions.Where(o => o.Status == SessionStatus.InGame).ToArray();
// Update client acks, which is used to figure out what data needs to be sent to clients
// This only needs SessionData which isn't touched during GetPVSData or ProcessCollections.
var ackJob = _pvs.ProcessQueuedAcks();
// Update entity positions in PVS chunks/collections
// TODO disable processing if culling is disabled? Need to check if toggling PVS breaks anything.
// TODO parallelize?
@@ -189,11 +194,7 @@ Oldest acked clients: {string.Join(", ", players)}
pvsData = GetPVSData(players);
}
// Update client acks, which is used to figure out what data needs to be sent to clients
using (_usageHistogram.WithLabels("Process Acks").NewTimer())
{
_pvs.ProcessQueuedAcks();
}
ackJob.WaitOne();
// Construct & send the game state to each player.
GameTick oldestAck;

View File

@@ -51,6 +51,8 @@ internal sealed class ParallelManager : IParallelManagerInternal
public event Action? ParallelCountChanged;
public int ParallelProcessCount { get; private set; }
public static readonly ManualResetEventSlim DummyResetEvent = new(true);
// Without pooling it's hard to keep task allocations down for classes
// This lets us avoid re-allocating the ManualResetEventSlims constantly when we just need a way to signal job completion.