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>())
|
||||
{
|
||||
var instance = _typeFactory.CreateInstance<JsonConverter>(converter);
|
||||
(instance as IAdminLogConverter)?.Init(_dependencies);
|
||||
_jsonOptions.Converters.Add(instance);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ public sealed partial class AdminLogManager : SharedAdminLogManager, IAdminLogMa
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IDynamicTypeFactory _typeFactory = default!;
|
||||
[Dependency] private readonly IReflectionManager _reflection = default!;
|
||||
[Dependency] private readonly IDependencyCollection _dependencies = default!;
|
||||
|
||||
public const string SawmillId = "admin.logs";
|
||||
|
||||
|
||||
@@ -3,8 +3,17 @@ using System.Text.Json.Serialization;
|
||||
|
||||
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)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Content.Server.Administration.Logs.Converters;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
[BaseTypeRequired(typeof(AdminLogConverter<>))]
|
||||
[MeansImplicitUse]
|
||||
public sealed class AdminLogConverterAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
@@ -6,7 +6,14 @@ namespace Content.Server.Administration.Logs.Converters;
|
||||
[AdminLogConverter]
|
||||
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)
|
||||
{
|
||||
@@ -29,6 +36,9 @@ public sealed class EntityUidConverter : AdminLogConverter<EntityUid>
|
||||
|
||||
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]
|
||||
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)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
|
||||
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.WriteString("name", entityManager.GetComponent<MetaDataComponent>(playerEntity).EntityName);
|
||||
|
||||
Reference in New Issue
Block a user