diff --git a/backend/FwLite/LocalWebApp/BackgroundSyncService.cs b/backend/FwLite/LocalWebApp/BackgroundSyncService.cs index 33767139f..cc14a168a 100644 --- a/backend/FwLite/LocalWebApp/BackgroundSyncService.cs +++ b/backend/FwLite/LocalWebApp/BackgroundSyncService.cs @@ -14,7 +14,7 @@ public class BackgroundSyncService( { private readonly Channel _syncResultsChannel = Channel.CreateUnbounded(); - public void TriggerSync(Guid projectId) + public void TriggerSync(Guid projectId, Guid? ignoredClientId = null) { var projectData = CurrentProjectService.LookupProjectById(memoryCache, projectId); if (projectData is null) @@ -22,6 +22,11 @@ public void TriggerSync(Guid projectId) logger.LogWarning("Received project update for unknown project {ProjectId}", projectId); return; } + if (ignoredClientId == projectData.ClientId) + { + logger.LogInformation("Received project update for {ProjectId} triggered by my own change, ignoring", projectId); + return; + } var crdtProject = projectsService.GetProject(projectData.Name); if (crdtProject is null) diff --git a/backend/FwLite/LocalWebApp/CrdtHttpSyncService.cs b/backend/FwLite/LocalWebApp/CrdtHttpSyncService.cs index 6c85a4552..85e06783e 100644 --- a/backend/FwLite/LocalWebApp/CrdtHttpSyncService.cs +++ b/backend/FwLite/LocalWebApp/CrdtHttpSyncService.cs @@ -57,11 +57,11 @@ public async ValueTask CreateProjectSyncable(ProjectData project) return NullSyncable.Instance; } - return new CrdtProjectSync(RestService.For(client, refitSettings), project.Id, project.OriginDomain, this); + return new CrdtProjectSync(RestService.For(client, refitSettings), project.Id, project.ClientId , project.OriginDomain, this); } } -public class CrdtProjectSync(ISyncHttp restSyncClient, Guid projectId, string originDomain, CrdtHttpSyncService httpSyncService) : ISyncable +public class CrdtProjectSync(ISyncHttp restSyncClient, Guid projectId, Guid clientId, string originDomain, CrdtHttpSyncService httpSyncService) : ISyncable { public ValueTask ShouldSync() { @@ -70,7 +70,7 @@ public ValueTask ShouldSync() async Task ISyncable.AddRangeFromSync(IEnumerable commits) { - await restSyncClient.AddRange(projectId, commits); + await restSyncClient.AddRange(projectId, commits, clientId); } async Task> ISyncable.GetChanges(SyncState otherHeads) @@ -104,7 +104,7 @@ public interface ISyncHttp Task HealthCheck(); [Post("/api/crdt/{id}/add")] - internal Task AddRange(Guid id, IEnumerable commits); + internal Task AddRange(Guid id, IEnumerable commits, Guid? clientId); [Get("/api/crdt/{id}/get")] internal Task GetSyncState(Guid id); diff --git a/backend/FwLite/LocalWebApp/Services/LexboxProjectService.cs b/backend/FwLite/LocalWebApp/Services/LexboxProjectService.cs index 72cf51e4d..28ecbccff 100644 --- a/backend/FwLite/LocalWebApp/Services/LexboxProjectService.cs +++ b/backend/FwLite/LocalWebApp/Services/LexboxProjectService.cs @@ -90,10 +90,10 @@ public async Task ListenForProjectChanges(ProjectData projectData, CancellationT //it would be cleaner to pass the callback in to this method however it's not supposed to be generic, it should always trigger a sync connection.On(nameof(IProjectChangeListener.OnProjectUpdated), - (Guid projectId) => + (Guid projectId, Guid? clientId) => { logger.LogInformation("Received project update for {ProjectId}, triggering sync", projectId); - backgroundSyncService.TriggerSync(projectId); + backgroundSyncService.TriggerSync(projectId, clientId); return Task.CompletedTask; }); diff --git a/backend/FwLite/MiniLcm/Push/IProjectChangeListener.cs b/backend/FwLite/MiniLcm/Push/IProjectChangeListener.cs index 28f76dc2f..88e886369 100644 --- a/backend/FwLite/MiniLcm/Push/IProjectChangeListener.cs +++ b/backend/FwLite/MiniLcm/Push/IProjectChangeListener.cs @@ -2,5 +2,5 @@ public interface IProjectChangeListener { - Task OnProjectUpdated(Guid projectId); + Task OnProjectUpdated(Guid projectId, Guid? clientId); } diff --git a/backend/LexBoxApi/Controllers/CrdtController.cs b/backend/LexBoxApi/Controllers/CrdtController.cs index 391782bc0..445aaff97 100644 --- a/backend/LexBoxApi/Controllers/CrdtController.cs +++ b/backend/LexBoxApi/Controllers/CrdtController.cs @@ -28,7 +28,7 @@ public async Task> GetSyncState(Guid projectId) } [HttpPost("{projectId}/add")] - public async Task Add(Guid projectId, [FromBody] ServerCommit[] commits) + public async Task Add(Guid projectId, [FromBody] ServerCommit[] commits, Guid? clientId) { await permissionService.AssertCanSyncProject(projectId); foreach (var commit in commits) @@ -38,7 +38,7 @@ public async Task Add(Guid projectId, [FromBody] ServerCommit[] co } await dbContext.SaveChangesAsync(); - await hubContext.Clients.Group(CrdtProjectChangeHub.ProjectGroup(projectId)).OnProjectUpdated(projectId); + await hubContext.Clients.Group(CrdtProjectChangeHub.ProjectGroup(projectId)).OnProjectUpdated(projectId, clientId); return Ok(); }