65 lines
2.0 KiB
C#
65 lines
2.0 KiB
C#
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;
|
||
}
|
||
}
|