Skip to content

Commit

Permalink
refactor: adding profile markers to common server methods
Browse files Browse the repository at this point in the history
  • Loading branch information
James-Frowen committed Jul 4, 2024
1 parent 365c319 commit 0e7791d
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 4 deletions.
9 changes: 8 additions & 1 deletion Assets/Mirage/Runtime/MessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
using System.Collections.Generic;
using Mirage.Logging;
using Mirage.Serialization;
using Unity.Profiling;
using UnityEngine;

namespace Mirage
{
public class MessageHandler : IMessageReceiver
{
private static readonly ProfilerMarker handleMessageMarker = new ProfilerMarker(nameof(HandleMessage));
private static readonly ILogger logger = LogFactory.GetLogger<MessageHandler>();

private readonly bool _disconnectOnException;
Expand Down Expand Up @@ -47,7 +49,10 @@ void AdapterFunction(INetworkPlayer player, NetworkReader reader)

if (logger.LogEnabled()) logger.Log($"Receiving {typeof(T)} from {player}");

handler.Invoke(player, message);
using (var _ = MessageIdCache<T>.ReceiveMarker.Auto())
{
handler.Invoke(player, message);
}
}
return AdapterFunction;
}
Expand All @@ -73,6 +78,8 @@ public void ClearHandlers()

public void HandleMessage(INetworkPlayer player, ArraySegment<byte> packet)
{
using var _ = handleMessageMarker.Auto();

using (var networkReader = NetworkReaderPool.GetReader(packet, _objectLocator))
{

Expand Down
12 changes: 12 additions & 0 deletions Assets/Mirage/Runtime/NetworkIdentity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Mirage.Logging;
using Mirage.RemoteCalls;
using Mirage.Serialization;
using Unity.Profiling;
using UnityEngine;
using UnityEngine.Serialization;

Expand Down Expand Up @@ -103,6 +104,12 @@ namespace Mirage
[HelpURL("https://miragenet.github.io/Mirage/docs/components/network-identity")]
public sealed class NetworkIdentity : MonoBehaviour
{
private static readonly ProfilerMarker rebuildObserversMarker = new ProfilerMarker(nameof(RebuildObservers));
private static readonly ProfilerMarker onSerializeAllInitialMarker = new ProfilerMarker("OnSerializeAll_Initial");
private static readonly ProfilerMarker onSerializeAllPartialMarker = new ProfilerMarker("OnSerializeAll_Partial");
private static readonly ProfilerMarker onDeserializeAllInitialMarker = new ProfilerMarker("OnDeserializeAll_Initial");
private static readonly ProfilerMarker onDeserializeAllPartialMarker = new ProfilerMarker("OnSerializeAll_Partial");

private static readonly ILogger logger = LogFactory.GetLogger<NetworkIdentity>();

public NetworkSpawnSettings SpawnSettings = NetworkSpawnSettings.Default;
Expand Down Expand Up @@ -675,6 +682,8 @@ private void OnSerialize(int i, NetworkBehaviour comp, NetworkWriter writer, boo
/// <param name="observersWriter"></param>
internal (int ownerWritten, int observersWritten) OnSerializeAll(bool initialState, NetworkWriter ownerWriter, NetworkWriter observersWriter)
{
using var _ = (initialState ? onSerializeAllInitialMarker : onSerializeAllPartialMarker).Auto();

// how many times it written to (NOT BYTES)
var ownerWritten = 0;
var observersWritten = 0;
Expand Down Expand Up @@ -765,6 +774,8 @@ internal bool StillDirty()

internal void OnDeserializeAll(NetworkReader reader, bool initialState)
{
using var _ = (initialState ? onDeserializeAllInitialMarker : onDeserializeAllPartialMarker).Auto();

// set InitialState before deserializing so that syncvar hooks and other methods can check it
InitialState = initialState;

Expand Down Expand Up @@ -979,6 +990,7 @@ internal void GetNewObservers(HashSet<INetworkPlayer> observersSet, bool initial
/// <param name="initialize">True if this is the first time.</param>
public void RebuildObservers(bool initialize)
{
using var _ = rebuildObserversMarker.Auto();
// call OnRebuildObservers function
GetNewObservers(newObservers, initialize);

Expand Down
11 changes: 11 additions & 0 deletions Assets/Mirage/Runtime/NetworkPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Mirage.Logging;
using Mirage.Serialization;
using Mirage.SocketLayer;
using Unity.Profiling;
using UnityEngine;

namespace Mirage
Expand All @@ -20,6 +21,9 @@ namespace Mirage
/// </remarks>
public sealed class NetworkPlayer : INetworkPlayer
{
private static readonly ProfilerMarker sendMessageMarker = new ProfilerMarker("SendMessage");
private static readonly ProfilerMarker sendBytesMarker = new ProfilerMarker("SendBytes");
private static readonly ProfilerMarker sendNotifyMarket = new ProfilerMarker("SendNotify");
private static readonly ILogger logger = LogFactory.GetLogger(typeof(NetworkPlayer));

private readonly HashSet<NetworkIdentity> _visList = new HashSet<NetworkIdentity>();
Expand Down Expand Up @@ -173,6 +177,9 @@ public NetworkPlayer(IConnection connection, bool isHost)
/// <returns></returns>
public void Send<T>(T message, Channel channelId = Channel.Reliable)
{
using var _ = sendMessageMarker.Auto();
using var __ = MessageIdCache<T>.SendMarker.Auto();

if (_isDisconnected) { return; }

using (var writer = NetworkWriterPool.GetWriter())
Expand All @@ -194,6 +201,8 @@ public void Send<T>(T message, Channel channelId = Channel.Reliable)
/// <param name="channelId"></param>
public void Send(ArraySegment<byte> segment, Channel channelId = Channel.Reliable)
{
using var _ = sendBytesMarker.Auto();

if (_isDisconnected) { return; }

if (channelId == Channel.Reliable)
Expand All @@ -215,6 +224,8 @@ public void Send(ArraySegment<byte> segment, Channel channelId = Channel.Reliabl
/// <returns></returns>
public void Send<T>(T message, INotifyCallBack callBacks)
{
using var _ = sendNotifyMarket.Auto();

if (_isDisconnected) { return; }

using (var writer = NetworkWriterPool.GetWriter())
Expand Down
9 changes: 7 additions & 2 deletions Assets/Mirage/Runtime/NetworkServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Mirage.Logging;
using Mirage.Serialization;
using Mirage.SocketLayer;
using Unity.Profiling;
using UnityEngine;
using UnityEngine.Serialization;

Expand All @@ -23,6 +24,7 @@ namespace Mirage
[DisallowMultipleComponent]
public class NetworkServer : MonoBehaviour
{
private static readonly ProfilerMarker sendToManyMarker = new ProfilerMarker(nameof(SendToMany));
private static readonly ILogger logger = LogFactory.GetLogger(typeof(NetworkServer));

public bool EnablePeerMetrics;
Expand Down Expand Up @@ -478,7 +480,7 @@ internal void AddLocalConnection(NetworkClient client, IConnection connection)

[Obsolete("Use SendToAll(msg, authenticatedOnly, excludeLocalPlayer, channelId) instead")]
public void SendToAll<T>(T msg, bool excludeLocalPlayer, Channel channelId = Channel.Reliable) => SendToAll(msg, authenticatedOnly: false, excludeLocalPlayer, channelId);

public void SendToAll<T>(T msg, bool authenticatedOnly, bool excludeLocalPlayer, Channel channelId = Channel.Reliable)
{
if (authenticatedOnly)
Expand Down Expand Up @@ -562,10 +564,13 @@ public static void SendToMany<T>(List<INetworkPlayer> players, T msg, Channel ch

/// <summary>
/// Sends to list of players.
/// <para>All other SendTo... functions call this, it dooes not do any extra checks, just serializes message if not empty, then sends it</para>
/// <para>All other SendTo... functions call this, it does not do any extra checks, just serializes message if not empty, then sends it</para>
/// </summary>
public static void SendToMany<T>(IReadOnlyList<INetworkPlayer> players, T msg, Channel channelId = Channel.Reliable)
{
using var _ = sendToManyMarker.Auto();
using var __ = MessageIdCache<T>.SendMarker.Auto();

// avoid serializing when list is empty
if (players.Count == 0)
return;
Expand Down
9 changes: 8 additions & 1 deletion Assets/Mirage/Runtime/Serialization/MessagePacker.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using Unity.Profiling;

namespace Mirage.Serialization
{
Expand All @@ -11,6 +12,9 @@ namespace Mirage.Serialization
public static class MessageIdCache<T>
{
public static readonly int Id = MessagePacker.GetId(typeof(T));

public static readonly ProfilerMarker SendMarker = new ProfilerMarker($"Send_{typeof(T).Name}");
public static readonly ProfilerMarker ReceiveMarker = new ProfilerMarker($"Handle_{typeof(T).Name}");
}

// message packing all in one place, instead of constructing headers in all
Expand All @@ -26,6 +30,7 @@ public static class MessageIdCache<T>
// (probably even shorter)
public static class MessagePacker
{
private static readonly ProfilerMarker packMarker = new ProfilerMarker(nameof(Pack));
/// <summary>
/// Backing field for <see cref="MessageTypes"/>
/// </summary>
Expand Down Expand Up @@ -82,11 +87,13 @@ public static int GetId(Type type)
// and do an allocation free send before recycling it.
public static void Pack<T>(T message, NetworkWriter writer)
{
using var _ = packMarker.Auto();

// if it is a value type, just use typeof(T) to avoid boxing
// this works because value types cannot be derived
// if it is a reference type (for example IMessageBase),
// ask the message for the real type
var id = default(T) == null && message != null
var id = default(T) == null && message != null
// for class we need to use GetType incase T is base class
? GetId(message.GetType())
// for struct, we can use the cached Id
Expand Down
21 changes: 21 additions & 0 deletions Assets/Mirage/Runtime/ServerObjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Mirage.Logging;
using Mirage.RemoteCalls;
using Mirage.Serialization;
using Unity.Profiling;
using UnityEngine;
using Object = UnityEngine.Object;

Expand All @@ -22,7 +23,15 @@ namespace Mirage
[DisallowMultipleComponent]
public class ServerObjectManager : MonoBehaviour
{
private static readonly ProfilerMarker spawnMarker = new ProfilerMarker(nameof(SpawnSceneObjects));
private static readonly ProfilerMarker addCharacterMarker = new ProfilerMarker(nameof(AddCharacter));
private static readonly ProfilerMarker destroyObjectMarker = new ProfilerMarker(nameof(DestroyObject));
private static readonly ProfilerMarker spawnVisibleObjectsMarker = new ProfilerMarker(nameof(SpawnVisibleObjects));
private static readonly ProfilerMarker spawnSceneObjectsMarker = new ProfilerMarker(nameof(SpawnSceneObjects));
private static readonly ProfilerMarker sendSpawnMessageMarker = new ProfilerMarker(nameof(SendSpawnMessage));

private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerObjectManager));

/// <summary>HashSet for NetworkIdentity that can be re-used without allocation</summary>
private static HashSet<NetworkIdentity> _skipCache = new HashSet<NetworkIdentity>();
/// <summary>HashSet for NetworkIdentity that can be re-used without allocation</summary>
Expand Down Expand Up @@ -196,6 +205,8 @@ public void AddCharacter(INetworkPlayer player, NetworkIdentity character, int p
/// <exception cref="ArgumentException">throw when the player already has a character</exception>
public void AddCharacter(INetworkPlayer player, NetworkIdentity identity)
{
using var _ = addCharacterMarker.Auto();

// cannot have an existing player object while trying to Add another.
if (player.HasCharacter)
{
Expand Down Expand Up @@ -347,6 +358,8 @@ public void Spawn(NetworkIdentity identity, INetworkPlayer owner)
/// </summary>
public void Spawn(NetworkIdentity identity)
{
using var _ = spawnMarker.Auto();

if (!_server || !_server.Active)
{
throw new InvalidOperationException("NetworkServer is not active. Cannot spawn objects without an active server.");
Expand Down Expand Up @@ -379,6 +392,8 @@ public void Spawn(NetworkIdentity identity)

internal void SendSpawnMessage(NetworkIdentity identity, INetworkPlayer player)
{
using var _ = sendSpawnMessageMarker.Auto();

logger.Assert(player.IsAuthenticated || !(identity.Visibility is AlwaysVisible), // can't use `is not` in unity2020
"SendSpawnMessage should only be called if player is authenticated, or there is custom visibility");
if (logger.LogEnabled()) logger.Log($"Server SendSpawnMessage: name={identity.name} sceneId={identity.SceneId:X} netId={identity.NetId}");
Expand Down Expand Up @@ -514,6 +529,8 @@ public void Destroy(NetworkIdentity identity, bool destroyServerObject = true)

private void DestroyObject(NetworkIdentity identity, bool destroyServerObject)
{
using var _ = destroyObjectMarker.Auto();

if (logger.LogEnabled()) logger.Log("DestroyObject instance:" + identity.NetId);

_server.World.RemoveIdentity(identity);
Expand Down Expand Up @@ -568,6 +585,8 @@ internal bool ValidateSceneObject(NetworkIdentity identity)
/// <exception cref="InvalidOperationException">Thrown when server is not active</exception>
public void SpawnSceneObjects()
{
using var _ = spawnSceneObjectsMarker.Auto();

// only if server active
if (!_server || !_server.Active)
throw new InvalidOperationException("Server was not active");
Expand Down Expand Up @@ -640,6 +659,8 @@ public void SpawnVisibleObjects(INetworkPlayer player, bool ignoreHasCharacter,
/// <param name="skip">NetworkIdentity to skip when spawning. Can be null</param>
public void SpawnVisibleObjects(INetworkPlayer player, bool ignoreHasCharacter, HashSet<NetworkIdentity> skip)
{
using var _ = spawnVisibleObjectsMarker.Auto();

// todo Call player.RemoveAllVisibleObjects() first so that it will send spawn message for objects destroyed in scene change

if (!ignoreHasCharacter && !player.HasCharacter)
Expand Down
3 changes: 3 additions & 0 deletions Assets/Mirage/Runtime/SyncVarReceiver.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Mirage.Logging;
using Mirage.Serialization;
using Unity.Profiling;
using UnityEngine;

namespace Mirage
Expand All @@ -9,6 +10,7 @@ namespace Mirage
/// </summary>
public class SyncVarReceiver
{
private static readonly ProfilerMarker onUpdateVarsMessageMarker = new ProfilerMarker(nameof(OnUpdateVarsMessage));
private static readonly ILogger logger = LogFactory.GetLogger(typeof(SyncVarReceiver));

private readonly IObjectLocator _objectLocator;
Expand Down Expand Up @@ -46,6 +48,7 @@ public SyncVarReceiver(NetworkServer server, IObjectLocator objectLocator)

private void OnUpdateVarsMessage(INetworkPlayer sender, UpdateVarsMessage msg)
{
using var _ = onUpdateVarsMessageMarker.Auto();
if (logger.LogEnabled()) logger.Log("SyncVarReceiver.OnUpdateVarsMessage " + msg.NetId);

if (_objectLocator.TryGetIdentity(msg.NetId, out var localObject))
Expand Down
7 changes: 7 additions & 0 deletions Assets/Mirage/Runtime/SyncVarSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using Mirage.Logging;
using Mirage.Serialization;
using Unity.Profiling;
using UnityEngine;

namespace Mirage
Expand All @@ -11,11 +12,14 @@ namespace Mirage
/// </summary>
public class SyncVarSender
{
private static readonly ProfilerMarker syncVarSenderMarker = new ProfilerMarker(nameof(SyncVarSender));
private static readonly ProfilerMarker sendUpdateVarsMessageMarker = new ProfilerMarker(nameof(SendUpdateVarsMessage));
private static readonly ILogger logger = LogFactory.GetLogger<SyncVarSender>();

private readonly HashSet<NetworkIdentity> _dirtyObjects = new HashSet<NetworkIdentity>();
private readonly List<NetworkIdentity> _dirtyObjectsTmp = new List<NetworkIdentity>();


public void AddDirtyObject(NetworkIdentity dirty)
{
var added = _dirtyObjects.Add(dirty);
Expand All @@ -25,6 +29,8 @@ public void AddDirtyObject(NetworkIdentity dirty)

internal void Update()
{
using var _ = syncVarSenderMarker.Auto();

if (_dirtyObjects.Count == 0)
return;

Expand Down Expand Up @@ -70,6 +76,7 @@ internal void Update()

internal static void SendUpdateVarsMessage(NetworkIdentity identity)
{
using var _ = sendUpdateVarsMessageMarker.Auto();
// one writer for owner, one for observers
using (PooledNetworkWriter ownerWriter = NetworkWriterPool.GetWriter(), observersWriter = NetworkWriterPool.GetWriter())
{
Expand Down

0 comments on commit 0e7791d

Please sign in to comment.