fix: Fixes serialization threading, moves world save to end of loop, and eliminates Parallel.ForEach. (#1530)
This commit is contained in:
parent
e18115dd94
commit
1f0acddc46
12 changed files with 228 additions and 58 deletions
|
|
@ -20,7 +20,6 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Server.Logging;
|
||||
|
||||
namespace Server;
|
||||
|
|
@ -55,13 +54,10 @@ public class GenericEntityPersistence<T> : Persistence, IGenericEntityPersistenc
|
|||
|
||||
public override void Serialize()
|
||||
{
|
||||
// TODO: Hand off to a scheduler instead
|
||||
Parallel.ForEach(EntitiesBySerial.Values, SerializeEntity);
|
||||
}
|
||||
|
||||
protected virtual void SerializeEntity(T entity)
|
||||
{
|
||||
entity.Serialize(World.SerializedTypes);
|
||||
foreach (var entity in EntitiesBySerial.Values)
|
||||
{
|
||||
World.PushToCache(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteSnapshot(string basePath)
|
||||
|
|
@ -160,6 +156,7 @@ public class GenericEntityPersistence<T> : Persistence, IGenericEntityPersistenc
|
|||
_pendingAdd[entity.Serial] = entity;
|
||||
break;
|
||||
}
|
||||
case WorldState.PendingSave:
|
||||
case WorldState.Running:
|
||||
{
|
||||
ref var entityEntry = ref CollectionsMarshal.GetValueRefOrAddDefault(EntitiesBySerial, entity.Serial, out bool exists);
|
||||
|
|
@ -216,6 +213,7 @@ public class GenericEntityPersistence<T> : Persistence, IGenericEntityPersistenc
|
|||
_pendingDelete[entity.Serial] = entity;
|
||||
break;
|
||||
}
|
||||
case WorldState.PendingSave:
|
||||
case WorldState.Running:
|
||||
{
|
||||
EntitiesBySerial.Remove(entity.Serial);
|
||||
|
|
@ -299,6 +297,7 @@ public class GenericEntityPersistence<T> : Persistence, IGenericEntityPersistenc
|
|||
|
||||
return null;
|
||||
}
|
||||
case WorldState.PendingSave:
|
||||
case WorldState.Running:
|
||||
{
|
||||
return EntitiesBySerial.TryGetValue(serial, out var entity) ? entity as R : null;
|
||||
|
|
|
|||
|
|
@ -14,25 +14,33 @@
|
|||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Server;
|
||||
|
||||
public abstract class GenericPersistence : Persistence
|
||||
public abstract class GenericPersistence : Persistence, IGenericSerializable
|
||||
{
|
||||
private BufferWriter _saveBuffer;
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public GenericPersistence(string name, int priority) : base(priority) => Name = name;
|
||||
|
||||
public override void Serialize()
|
||||
{
|
||||
_saveBuffer ??= new BufferWriter(true, World.SerializedTypes);
|
||||
_saveBuffer.Seek(0, SeekOrigin.Begin);
|
||||
World.PushToCache(this);
|
||||
}
|
||||
|
||||
Serialize(_saveBuffer);
|
||||
public long SavePosition { get; set; }
|
||||
|
||||
public BufferWriter SaveBuffer { get; set; }
|
||||
|
||||
public void Serialize(ConcurrentQueue<Type> types)
|
||||
{
|
||||
SaveBuffer ??= new BufferWriter(true, types);
|
||||
|
||||
SaveBuffer.Seek(0, SeekOrigin.Begin);
|
||||
Serialize(SaveBuffer);
|
||||
}
|
||||
|
||||
public abstract void Serialize(IGenericWriter writer);
|
||||
|
|
@ -40,7 +48,7 @@ public abstract class GenericPersistence : Persistence
|
|||
public override void WriteSnapshot(string basePath)
|
||||
{
|
||||
string binPath = Path.Combine(basePath, Name, $"{Name}.bin");
|
||||
var buffer = _saveBuffer!.Buffer.AsSpan(0, (int)_saveBuffer.Position);
|
||||
var buffer = SaveBuffer!.Buffer.AsSpan(0, (int)SaveBuffer.Position);
|
||||
AdhocPersistence.WriteSnapshot(new FileInfo(binPath), buffer);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ using System.IO;
|
|||
|
||||
namespace Server;
|
||||
|
||||
public interface ISerializable
|
||||
public interface ISerializable : IGenericSerializable
|
||||
{
|
||||
// Should be serialized/deserialized with the index so it can be referenced by IGenericReader
|
||||
DateTime Created { get; set; }
|
||||
|
|
@ -48,7 +48,7 @@ public interface ISerializable
|
|||
}
|
||||
}
|
||||
|
||||
public void Serialize(ConcurrentQueue<Type> types)
|
||||
void IGenericSerializable.Serialize(ConcurrentQueue<Type> types)
|
||||
{
|
||||
SaveBuffer ??= new BufferWriter(true, types);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,8 +81,10 @@ public abstract class Persistence
|
|||
|
||||
internal static void SerializeAll()
|
||||
{
|
||||
// TODO: Hand off to a scheduler
|
||||
Parallel.ForEach(_registry, p => p.Serialize());
|
||||
foreach (var p in _registry)
|
||||
{
|
||||
p.Serialize();
|
||||
}
|
||||
}
|
||||
|
||||
internal static void PostSerializeAll()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue