Initial
This commit is contained in:
64
LehrerApp.Sync/ConflictResolver.cs
Normal file
64
LehrerApp.Sync/ConflictResolver.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using LehrerApp.Sync.Models;
|
||||
|
||||
namespace LehrerApp.Sync;
|
||||
|
||||
/// <summary>
|
||||
/// Entscheidet bei kollidierenden Events welcher gewinnt.
|
||||
/// Desktop hat Vorrang vor Companion. Bei Gleichstand gewinnt der spätere Timestamp.
|
||||
/// </summary>
|
||||
public class ConflictResolver
|
||||
{
|
||||
private readonly EventQueue _queue;
|
||||
|
||||
public ConflictResolver(EventQueue queue)
|
||||
{
|
||||
_queue = queue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prüft ob ein Remote-Event mit einem lokalen Event kollidiert.
|
||||
/// Gibt null zurück wenn kein Konflikt besteht.
|
||||
/// </summary>
|
||||
public ConflictEntry? TryResolve(SyncEvent remoteEvent, string localDeviceId)
|
||||
{
|
||||
// Lokalen Event für dieselbe Entity suchen
|
||||
var localEvent = _queue.GetPending()
|
||||
.FirstOrDefault(e =>
|
||||
e.EntityType == remoteEvent.EntityType &&
|
||||
e.EntityId == remoteEvent.EntityId &&
|
||||
e.DeviceId != remoteEvent.DeviceId);
|
||||
|
||||
if (localEvent is null)
|
||||
return null; // kein Konflikt – Remote-Event einfach anwenden
|
||||
|
||||
// Konflikt aufgelöst – Gewinner bestimmen
|
||||
var winner = DetermineWinner(localEvent, remoteEvent);
|
||||
var resolution = winner == localEvent ? "LocalWon" : "RemoteWon";
|
||||
|
||||
// Wenn Remote gewinnt: lokalen Event aus Queue entfernen
|
||||
if (winner == remoteEvent)
|
||||
_queue.Acknowledge([localEvent.EventId]);
|
||||
|
||||
return new ConflictEntry
|
||||
{
|
||||
LocalEvent = localEvent,
|
||||
RemoteEvent = remoteEvent,
|
||||
Resolution = resolution,
|
||||
};
|
||||
}
|
||||
|
||||
private static SyncEvent DetermineWinner(SyncEvent local, SyncEvent remote)
|
||||
{
|
||||
// Regel 1: Desktop schlägt Companion
|
||||
if (local.DeviceType == DeviceType.Desktop &&
|
||||
remote.DeviceType == DeviceType.Companion)
|
||||
return local;
|
||||
|
||||
if (remote.DeviceType == DeviceType.Desktop &&
|
||||
local.DeviceType == DeviceType.Companion)
|
||||
return remote;
|
||||
|
||||
// Regel 2: Späterer Timestamp gewinnt
|
||||
return local.Timestamp >= remote.Timestamp ? local : remote;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user