Skip to content
37 changes: 9 additions & 28 deletions com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace MLAPI
/// The main component of the library
/// </summary>
[AddComponentMenu("MLAPI/NetworkManager", -100)]
public class NetworkManager : MonoBehaviour, INetworkUpdateSystem
public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTransportProvider
Comment thread
0xFA11 marked this conversation as resolved.
{
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
Expand All @@ -56,10 +56,6 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem
internal RpcQueueContainer RpcQueueContainer { get; private set; }
internal NetworkTickSystem NetworkTickSystem { get; private set; }

public delegate void PerformanceDataEventHandler(PerformanceTickData profilerData);

public static event PerformanceDataEventHandler OnPerformanceDataEvent;

/// <summary>
/// A synchronized time, represents the time in seconds since the server application started. Is replicated across all clients
/// </summary>
Expand Down Expand Up @@ -386,6 +382,8 @@ private void Init(bool server)
NetworkConfig.NetworkTransport.ResetChannelCache();

NetworkConfig.NetworkTransport.Init();

ProfilerNotifier.Initialize(this);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something we always do even if we're not running in the editor? Or put another way, what if I'm shipping the game and don't want the profiler overhead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the same vein, in NetworkProfiler.cs circa line 651 (and I know this is from a previous commit) we unconditionally call ProfilerBeginTick

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this was an intentional choice on our end, since there may be runtime tools that need this data. That doesn't mean users might not want to omit the profiling from the build, but we haven't provided that utility yet. Since we're just tracking counters in v1 the overhead is very small, but as we expand the data set this is going to be important. Maybe we could add a #if !MLAPI_DISABLE_STATS so that it's on by default, but users can turn it off with the compiler configuration.

I'd suggest that this belongs in a separate PR though. Kamau isn't introducing profiling into release builds with this PR, he's just refactoring functionality that already exists.

}

/// <summary>
Expand Down Expand Up @@ -1483,34 +1481,17 @@ internal void HandleApproval(ulong clientId, bool createPlayerObject, ulong? pla

private void ProfilerBeginTick()
{
PerformanceDataManager.BeginNewTick();
if (NetworkConfig.NetworkTransport is ITransportProfilerData profileTransport)
{
profileTransport.BeginNewTick();
}
ProfilerNotifier.ProfilerBeginTick();
}

private void NotifyProfilerListeners()
{
var data = PerformanceDataManager.GetData();
var eventHandler = OnPerformanceDataEvent;
if (eventHandler != null)
{
if (data != null)
{
if (NetworkConfig.NetworkTransport is ITransportProfilerData profileTransport)
{
var transportProfilerData = profileTransport.GetTransportProfilerData();
PerformanceDataManager.AddTransportData(transportProfilerData);
}
ProfilerNotifier.NotifyProfilerListeners();
}

eventHandler.Invoke(data);
}
else
{
NetworkLog.LogWarning($"No data available. Did you forget to call {nameof(PerformanceDataManager)}.{nameof(PerformanceDataManager.BeginNewTick)}() first?");
}
}
public ITransportProfilerData Transport
{
get { return NetworkConfig.NetworkTransport as ITransportProfilerData; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace MLAPI.Profiling
{
public interface IProfilableTransportProvider
{
ITransportProfilerData Transport { get; }
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using UnityEngine;

namespace MLAPI.Profiling
{
Expand All @@ -11,8 +12,9 @@ internal static class PerformanceDataManager
internal static void BeginNewTick()
{
s_TickId = Math.Max(s_TickId, 0);
s_TickId++;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a bugfix? Nice.

s_ProfilerData.Reset();
s_ProfilerData.TickId = s_TickId++;
s_ProfilerData.TickId = s_TickId;
}

internal static void Increment(string fieldName, int count = 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,13 @@ internal static class ProfilerCountersInfo
private static void RegisterMLAPIPerformanceEvent()
{
InitializeCounters();
NetworkManager.OnPerformanceDataEvent += OnPerformanceTickData;
ProfilerNotifier.OnPerformanceDataEvent += OnPerformanceTickData;
ProfilerNotifier.OnNoTickDataEvent += OnNoTickData;
}

private static void OnNoTickData()
{
Debug.LogWarning("There was a profiler event that was not captured in a tick");
}

private static void InitializeCounters()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using MLAPI.Logging;

namespace MLAPI.Profiling
{
public static class ProfilerNotifier

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so obviously this PR introduces stuff more than just tests right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, originally the PR was just tests but should probably update the commit message to refactor with the expanded scope

{
public delegate void PerformanceDataEventHandler(PerformanceTickData profilerData);

public static event PerformanceDataEventHandler OnPerformanceDataEvent;

public delegate void NoTickDataHandler();

public static event NoTickDataHandler OnNoTickDataEvent;

private static IProfilableTransportProvider s_ProfilableTransportProvider;
private static bool s_FailsafeCheck;

public static void Initialize(IProfilableTransportProvider profilableNetwork)
{
s_ProfilableTransportProvider = profilableNetwork
?? throw new ArgumentNullException(
$"{nameof(profilableNetwork)} was not set");
s_FailsafeCheck = false;
}

public static void ProfilerBeginTick()
{
PerformanceDataManager.BeginNewTick();
var transport = s_ProfilableTransportProvider.Transport;
transport?.BeginNewTick();
s_FailsafeCheck = true;
}

public static void NotifyProfilerListeners()
{
if (!s_FailsafeCheck)
return;

s_FailsafeCheck = false;

var data = PerformanceDataManager.GetData();
var eventHandler = OnPerformanceDataEvent;
if (eventHandler != null)
{
if (data != null)
{
var transport = s_ProfilableTransportProvider.Transport;
if (transport != null)
{
var transportProfilerData = transport.GetTransportProfilerData();

PerformanceDataManager.AddTransportData(transportProfilerData);
}

eventHandler.Invoke(data);
}
else
{
NetworkLog.LogWarning(
"No data available. Did you forget to call PerformanceDataManager.BeginNewTick() first?");
}
}
}

public static void Increment(string fieldName, int count = 1)
{
if (!s_FailsafeCheck)
{
OnNoTickDataEvent?.Invoke();
}

PerformanceDataManager.Increment(fieldName);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading