Fix S.T.Json holding integration instances live for long. (#13080)
This commit is contained in:
committed by
GitHub
parent
4bfc644a03
commit
896ffec8d9
@@ -24,6 +24,7 @@ public sealed partial class AdminLogManager
|
|||||||
foreach (var converter in _reflection.FindTypesWithAttribute<AdminLogConverterAttribute>())
|
foreach (var converter in _reflection.FindTypesWithAttribute<AdminLogConverterAttribute>())
|
||||||
{
|
{
|
||||||
var instance = _typeFactory.CreateInstance<JsonConverter>(converter);
|
var instance = _typeFactory.CreateInstance<JsonConverter>(converter);
|
||||||
|
(instance as IAdminLogConverter)?.Init(_dependencies);
|
||||||
_jsonOptions.Converters.Add(instance);
|
_jsonOptions.Converters.Add(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
|||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly IDynamicTypeFactory _typeFactory = default!;
|
[Dependency] private readonly IDynamicTypeFactory _typeFactory = default!;
|
||||||
[Dependency] private readonly IReflectionManager _reflection = default!;
|
[Dependency] private readonly IReflectionManager _reflection = default!;
|
||||||
|
[Dependency] private readonly IDependencyCollection _dependencies = default!;
|
||||||
|
|
||||||
public const string SawmillId = "admin.logs";
|
public const string SawmillId = "admin.logs";
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,17 @@ using System.Text.Json.Serialization;
|
|||||||
|
|
||||||
namespace Content.Server.Administration.Logs.Converters;
|
namespace Content.Server.Administration.Logs.Converters;
|
||||||
|
|
||||||
public abstract class AdminLogConverter<T> : JsonConverter<T>
|
public interface IAdminLogConverter
|
||||||
{
|
{
|
||||||
|
void Init(IDependencyCollection dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class AdminLogConverter<T> : JsonConverter<T>, IAdminLogConverter
|
||||||
|
{
|
||||||
|
public virtual void Init(IDependencyCollection dependencies)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace Content.Server.Administration.Logs.Converters;
|
|||||||
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
[BaseTypeRequired(typeof(AdminLogConverter<>))]
|
[BaseTypeRequired(typeof(AdminLogConverter<>))]
|
||||||
|
[MeansImplicitUse]
|
||||||
public sealed class AdminLogConverterAttribute : Attribute
|
public sealed class AdminLogConverterAttribute : Attribute
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,14 @@ namespace Content.Server.Administration.Logs.Converters;
|
|||||||
[AdminLogConverter]
|
[AdminLogConverter]
|
||||||
public sealed class EntityUidConverter : AdminLogConverter<EntityUid>
|
public sealed class EntityUidConverter : AdminLogConverter<EntityUid>
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IEntityManager _entities = default!;
|
// System.Text.Json actually keeps hold of your JsonSerializerOption instances in a cache on .NET 7.
|
||||||
|
// Use a weak reference to avoid holding server instances live too long in integration tests.
|
||||||
|
private WeakReference<IEntityManager> _entityManager = default!;
|
||||||
|
|
||||||
|
public override void Init(IDependencyCollection dependencies)
|
||||||
|
{
|
||||||
|
_entityManager = new WeakReference<IEntityManager>(dependencies.Resolve<IEntityManager>());
|
||||||
|
}
|
||||||
|
|
||||||
public static void Write(Utf8JsonWriter writer, EntityUid value, JsonSerializerOptions options, IEntityManager entities)
|
public static void Write(Utf8JsonWriter writer, EntityUid value, JsonSerializerOptions options, IEntityManager entities)
|
||||||
{
|
{
|
||||||
@@ -29,6 +36,9 @@ public sealed class EntityUidConverter : AdminLogConverter<EntityUid>
|
|||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, EntityUid value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, EntityUid value, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
Write(writer, value, options, _entities);
|
if (!_entityManager.TryGetTarget(out var entityManager))
|
||||||
|
throw new InvalidOperationException("EntityManager got garbage collected!");
|
||||||
|
|
||||||
|
Write(writer, value, options, entityManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,23 @@ namespace Content.Server.Administration.Logs.Converters;
|
|||||||
[AdminLogConverter]
|
[AdminLogConverter]
|
||||||
public sealed class PlayerSessionConverter : AdminLogConverter<SerializablePlayer>
|
public sealed class PlayerSessionConverter : AdminLogConverter<SerializablePlayer>
|
||||||
{
|
{
|
||||||
|
// System.Text.Json actually keeps hold of your JsonSerializerOption instances in a cache on .NET 7.
|
||||||
|
// Use a weak reference to avoid holding server instances live too long in integration tests.
|
||||||
|
private WeakReference<IEntityManager> _entityManager = default!;
|
||||||
|
|
||||||
|
public override void Init(IDependencyCollection dependencies)
|
||||||
|
{
|
||||||
|
_entityManager = new WeakReference<IEntityManager>(dependencies.Resolve<IEntityManager>());
|
||||||
|
}
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, SerializablePlayer value, JsonSerializerOptions options)
|
public override void Write(Utf8JsonWriter writer, SerializablePlayer value, JsonSerializerOptions options)
|
||||||
{
|
{
|
||||||
writer.WriteStartObject();
|
writer.WriteStartObject();
|
||||||
|
|
||||||
if (value.Player.AttachedEntity is {Valid: true} playerEntity)
|
if (value.Player.AttachedEntity is {Valid: true} playerEntity)
|
||||||
{
|
{
|
||||||
var entityManager = IoCManager.Resolve<IEntityManager>();
|
if (!_entityManager.TryGetTarget(out var entityManager))
|
||||||
|
throw new InvalidOperationException("EntityManager got garbage collected!");
|
||||||
|
|
||||||
writer.WriteNumber("id", (int) value.Player.AttachedEntity);
|
writer.WriteNumber("id", (int) value.Player.AttachedEntity);
|
||||||
writer.WriteString("name", entityManager.GetComponent<MetaDataComponent>(playerEntity).EntityName);
|
writer.WriteString("name", entityManager.GetComponent<MetaDataComponent>(playerEntity).EntityName);
|
||||||
|
|||||||
Reference in New Issue
Block a user