Пример #1
0
        public async Task ResolveWhenScriptAdded()
        {
            using (var store1 = GetDocumentStore())
                using (var store2 = GetDocumentStore())
                {
                    await GenerateConflicts(store1, store2);

                    var config = new ConflictSolver
                    {
                        ResolveByCollection = new Dictionary <string, ScriptResolver>
                        {
                            {
                                "Users", new ScriptResolver
                                {
                                    Script = "return {'Name':'Resolved'}"
                                }
                            }
                        }
                    };
                    await SetupReplicationAsync(store1, config, store2);

                    Assert.True(WaitForDocument <User>(store1, "foo/bar", u => u.Name == "Resolved"));
                    Assert.True(WaitForDocument <User>(store2, "foo/bar", u => u.Name == "Resolved"));
                }
        }
Пример #2
0
        private void HandleConflictResolverChange(DatabaseRecord newRecord)
        {
            if (newRecord == null)
            {
                ConflictSolverConfig = null;
                return;
            }

            if (ConflictSolverConfig == null && newRecord.ConflictSolverConfig == null)
            {
                return;
            }

            var conflictSolverChanged = ConflictSolverConfig?.ConflictResolutionChanged(newRecord.ConflictSolverConfig) ?? true;

            if (conflictSolverChanged)
            {
                if (_log.IsInfoEnabled)
                {
                    _log.Info("Conflict resolution was change.");
                }
                ConflictSolverConfig = newRecord.ConflictSolverConfig;
                ConflictResolver.RunConflictResolversOnce();
            }
        }
        /// <summary>
        /// Called when [activated].
        /// </summary>
        /// <param name="disposables">The disposables.</param>
        protected override void OnActivated(CompositeDisposable disposables)
        {
            BindOverlay();

            ReactiveUI.MessageBus.Current.Listen <NavigationEventArgs>()
            .Subscribe(s =>
            {
                ReactiveUI.MessageBus.Current.SendMessage(new ForceClosePopulsEventArgs());
                switch (s.State)
                {
                case NavigationState.ConflictSolver:
                    ConflictSolver.SelectedModCollection = s.SelectedCollection;
                    ConflictSolver.SelectedModsOrder     = s.SelectedMods;
                    ConflictSolver.Conflicts             = s.Results;
                    ConflictSolver.Reset();
                    AnimateTransitionAsync(false).ConfigureAwait(true);
                    break;

                default:
                    AnimateTransitionAsync(true).ConfigureAwait(true);
                    Main.Reset();
                    break;
                }
            }).DisposeWith(disposables);

            writingStateOperationHandler.Message.Subscribe(s =>
            {
                TriggerPreventShutdown(!s.CanShutdown);
            }).DisposeWith(disposables);

            base.OnActivated(disposables);
        }
Пример #4
0
        public async Task CreateConflictAndResolveItIncreaseTheRevisions()
        {
            using (var storeA = GetDocumentStore())
                using (var storeB = GetDocumentStore())
                {
                    await GenerateConflict(storeA, storeB);

                    Assert.Equal(2, WaitUntilHasConflict(storeA, "foo/bar").Length);
                    Assert.Equal(2, WaitUntilHasConflict(storeB, "foo/bar").Length);

                    Assert.Equal(2, WaitForValue(() => storeA.Commands().GetRevisionsFor("foo/bar").Count, 2));
                    Assert.Equal(2, WaitForValue(() => storeB.Commands().GetRevisionsFor("foo/bar").Count, 2));

                    var config = new ConflictSolver
                    {
                        ResolveToLatest = true
                    };

                    await SetupReplicationAsync(storeA, config, storeB);

                    Assert.True(WaitForDocument(storeA, "foo/bar"));
                    Assert.True(WaitForDocument(storeB, "foo/bar"));

                    Assert.Equal(3, WaitForValue(() => storeA.Commands().GetRevisionsFor("foo/bar").Count, 3));
                    Assert.Equal(3, WaitForValue(() => storeB.Commands().GetRevisionsFor("foo/bar").Count, 3));
                }
        }
Пример #5
0
 private void WriteConflictSolver(ConflictSolver conflictSolver)
 {
     if (conflictSolver == null)
     {
         _writer.WriteNull();
         return;
     }
     _context.Write(_writer, conflictSolver.ToJson());
 }
Пример #6
0
        private void TestBtn_Click(object sender, EventArgs e)
        {
            dd1 = new DirectoryData(CurrentPD.SourceDirectoryPath);
            dd2 = new DirectoryData(CurrentPD.TargetDirectoryPath);

            CurrentSession = ConflictSolver.FormConflictFileDataList(dd1, dd2);

            SyncClassifier.ClassifySyncDatas(CurrentSession, CurrentPD.StatementDataString);

            FillTheTable();
        }
Пример #7
0
        public void Initialize(DatabaseRecord record)
        {
            if (_isInitialized) //precaution -> probably not necessary, but still...
            {
                return;
            }

            ConflictSolverConfig = record.ConflictSolverConfig;
            ConflictResolver     = new ResolveConflictOnReplicationConfigurationChange(this, _log);
            ConflictResolver.RunConflictResolversOnce();
            _isInitialized.Raise();
        }
        public async Task ResolveWhenScriptAdded()
        {
            using (var store1 = GetDocumentStore(options: new Options
            {
                ModifyDatabaseRecord = record =>
                {
                    record.ConflictSolverConfig = new ConflictSolver
                    {
                        ResolveToLatest = false,
                        ResolveByCollection = new Dictionary <string, ScriptResolver>()
                    };
                }
            }))
                using (var store2 = GetDocumentStore(options: new Options
                {
                    ModifyDatabaseRecord = record =>
                    {
                        record.ConflictSolverConfig = new ConflictSolver
                        {
                            ResolveToLatest = false,
                            ResolveByCollection = new Dictionary <string, ScriptResolver>()
                        };
                    }
                }))
                {
                    await GenerateConflictsAndSetupMasterMasterReplication(store1, store2);

                    var config = new ConflictSolver
                    {
                        ResolveByCollection = new Dictionary <string, ScriptResolver>
                        {
                            {
                                "Users", new ScriptResolver
                                {
                                    Script = "return {'Name':'Resolved'}"
                                }
                            }
                        }
                    };
                    await UpdateConflictResolver(store1, config.ResolveByCollection, config.ResolveToLatest);

                    Assert.True(WaitForDocument <User>(store1, "foo/bar", u => u.Name == "Resolved"));
                    Assert.True(WaitForDocument <User>(store2, "foo/bar", u => u.Name == "Resolved"));
                }
        }
Пример #9
0
        public async Task ResolveWhenSettingDatabaseResolver()
        {
            using (var store1 = GetDocumentStore())
                using (var store2 = GetDocumentStore())
                {
                    await GenerateConflicts(store1, store2);

                    var storage1 = Server.ServerStore.DatabasesLandlord.TryGetOrCreateResourceStore(store1.Database).Result;

                    var config = new ConflictSolver
                    {
                        DatabaseResolverId = storage1.DbBase64Id
                    };
                    await SetupReplicationAsync(store1, config, store2);

                    Assert.True(WaitForDocument <User>(store1, "foo/bar", u => u.Name == "Store1"));
                    Assert.True(WaitForDocument <User>(store2, "foo/bar", u => u.Name == "Store1"));
                }
        }
Пример #10
0
        /// <summary>
        /// Called when [activated].
        /// </summary>
        /// <param name="disposables">The disposables.</param>
        protected override void OnActivated(CompositeDisposable disposables)
        {
            var state = NavigationState.Main;

            BindOverlay();

            ReactiveUI.MessageBus.Current.Listen <NavigationEventArgs>()
            .Subscribe(s =>
            {
                ReactiveUI.MessageBus.Current.SendMessage(new ForceClosePopulsEventArgs());
                state = s.State;
                switch (s.State)
                {
                case NavigationState.ConflictSolver:
                    ConflictSolver.SelectedModCollection = s.SelectedCollection;
                    ConflictSolver.SelectedModsOrder     = s.SelectedMods;
                    ConflictSolver.Conflicts             = s.Results;
                    ConflictSolver.Reset();
                    AnimateTransitionAsync(false).ConfigureAwait(true);
                    break;

                default:
                    AnimateTransitionAsync(true).ConfigureAwait(true);
                    Main.Reset();
                    break;
                }
            }).DisposeWith(disposables);

            writingStateOperationHandler.Subscribe(s =>
            {
                TriggerPreventShutdown(!s.CanShutdown);
            }).DisposeWith(disposables);

            RegisterHotkeyCommand = ReactiveCommand.CreateFromTask(async(string key) =>
            {
                if (!OverlayVisible)
                {
                    await hotkeyManager.HotKeyPressedAsync(state, key);
                }
            }).DisposeWith(disposables);

            base.OnActivated(disposables);
        }
Пример #11
0
        public async Task CreateConflictAndResolveItIncreaseTheRevisions(bool configureVersioning)
        {
            using (var storeA = GetDocumentStore())
                using (var storeB = GetDocumentStore())
                {
                    await GenerateConflict(storeA, storeB, configureVersioning);

                    Assert.Equal(2, WaitUntilHasConflict(storeA, "foo/bar").Length);
                    Assert.Equal(2, WaitUntilHasConflict(storeB, "foo/bar").Length);

                    if (configureVersioning)
                    {
                        using (var session = storeA.OpenSession())
                        {
                            Assert.Equal(2, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 2));
                        }
                        using (var session = storeB.OpenSession())
                        {
                            Assert.Equal(2, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 2));
                        }
                    }

                    var config = new ConflictSolver
                    {
                        ResolveToLatest = true
                    };

                    await SetupReplicationAsync(storeA, config, storeB);

                    Assert.True(WaitForDocument(storeA, "foo/bar"));
                    Assert.True(WaitForDocument(storeB, "foo/bar"));

                    using (var session = storeA.OpenSession())
                    {
                        Assert.Equal(3, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 3));
                    }
                    using (var session = storeB.OpenSession())
                    {
                        Assert.Equal(3, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 3));
                    }
                }
        }
Пример #12
0
        public async Task RunConflictResolversOnce(ConflictSolver solver, long index)
        {
            // update to larger index;
            if (ThreadingHelper.InterlockedExchangeMax(ref _processedRaftIndex, index) == false)
            {
                return;
            }

            try
            {
                using (await RunOnceAsync())
                {
                    if (Interlocked.Read(ref _processedRaftIndex) > index)
                    {
                        return;
                    }

                    UpdateScriptResolvers(solver);

                    if (ConflictsCount > 0 && solver?.IsEmpty() == false)
                    {
                        await ResolveConflictsInBackground(solver);
                    }
                }
            }
            catch (OperationCanceledException)
            {
                // shutdown
            }
            catch (ObjectDisposedException)
            {
                // shutdown
            }
            catch (Exception e)
            {
                if (_log.IsInfoEnabled)
                {
                    _log.Info("Failed to wait for a previous task of automatic conflict resolution", e);
                }
            }
        }
        public async Task CreateConflictAndResolveItIncreaseTheRevisions(bool configureVersioning)
        {
            using (var storeA = GetDocumentStore(options: new Options
            {
                ModifyDatabaseRecord = record =>
                {
                    record.ConflictSolverConfig = new ConflictSolver
                    {
                        ResolveToLatest = false,
                        ResolveByCollection = new Dictionary <string, ScriptResolver>()
                    };
                }
            }))
                using (var storeB = GetDocumentStore(options: new Options
                {
                    ModifyDatabaseRecord = record =>
                    {
                        record.ConflictSolverConfig = new ConflictSolver
                        {
                            ResolveToLatest = false,
                            ResolveByCollection = new Dictionary <string, ScriptResolver>()
                        };
                    }
                }))
                {
                    await GenerateConflictAndSetupMasterMasterReplication(storeA, storeB, configureVersioning);

                    Assert.Equal(2, WaitUntilHasConflict(storeA, "foo/bar").Length);
                    Assert.Equal(2, WaitUntilHasConflict(storeB, "foo/bar").Length);

                    if (configureVersioning)
                    {
                        using (var session = storeA.OpenSession())
                        {
                            Assert.Equal(2, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 2));
                        }
                        using (var session = storeB.OpenSession())
                        {
                            Assert.Equal(2, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 2));
                        }
                    }

                    var config = new ConflictSolver
                    {
                        ResolveToLatest = true
                    };

                    await UpdateConflictResolver(storeA, config.ResolveByCollection, config.ResolveToLatest);

                    Assert.True(WaitForDocument(storeA, "foo/bar"));
                    Assert.True(WaitForDocument(storeB, "foo/bar"));

                    using (var session = storeA.OpenSession())
                    {
                        Assert.Equal(3, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 3));
                    }
                    using (var session = storeB.OpenSession())
                    {
                        Assert.Equal(3, WaitForValue(() => session.Advanced.Revisions.GetMetadataFor("foo/bar").Count, 3));
                    }
                }
        }
Пример #14
0
 protected async Task SetupReplicationAsync(DocumentStore fromStore, ConflictSolver conflictSolver, params DocumentStore[] toStores)
 {
     await UpdateConflictResolver(fromStore, conflictSolver.ResolveByCollection, conflictSolver.ResolveToLatest);
     await SetupReplicationAsync(fromStore, toStores);
 }
Пример #15
0
        private async Task ResolveConflictsInBackground(ConflictSolver solver)
        {
            try
            {
                bool retry;
                do
                {
                    retry = false;
                    using (_database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
                        using (context.OpenReadTransaction())
                        {
                            var resolvedConflicts = new List <(DocumentConflict ResolvedConflict, long MaxConflictEtag, bool ResolvedToLatest)>();

                            var hadConflicts = false;

                            foreach (var conflicts in _database.DocumentsStorage.ConflictsStorage.GetAllConflictsBySameId(context))
                            {
                                if (_database.DatabaseShutdown.IsCancellationRequested)
                                {
                                    break;
                                }

                                hadConflicts = true;

                                var collection = conflicts[0].Collection;

                                var maxConflictEtag = conflicts.Max(x => x.Etag);

                                DocumentConflict resolved;
                                if (ScriptConflictResolversCache.TryGetValue(collection, out var scriptResolver) && scriptResolver != null)
                                {
                                    if (TryResolveConflictByScriptInternal(
                                            context,
                                            scriptResolver,
                                            conflicts,
                                            collection,
                                            resolvedConflict: out resolved))
                                    {
                                        resolved.Flags = resolved.Flags.Strip(DocumentFlags.FromReplication);
                                        resolvedConflicts.Add((resolved, maxConflictEtag, ResolvedToLatest: false));

                                        //stats.AddResolvedBy(collection + " Script", conflictList.Count);
                                        continue;
                                    }
                                }

                                if (solver?.ResolveToLatest == true)
                                {
                                    resolved       = ResolveToLatest(conflicts);
                                    resolved.Flags = resolved.Flags.Strip(DocumentFlags.FromReplication);
                                    resolvedConflicts.Add((resolved, maxConflictEtag, ResolvedToLatest: true));

                                    //stats.AddResolvedBy("ResolveToLatest", conflictList.Count);
                                }
                            }

                            if (hadConflicts == false || _database.DatabaseShutdown.IsCancellationRequested)
                            {
                                return;
                            }

                            if (resolvedConflicts.Count > 0)
                            {
                                var cmd = new PutResolvedConflictsCommand(_database.DocumentsStorage.ConflictsStorage, resolvedConflicts, this);
                                await _database.TxMerger.Enqueue(cmd);

                                retry = cmd.RequiresRetry;
                            }
                        }
                } while (retry);
            }
            catch (Exception e)
            {
                if (_log.IsInfoEnabled)
                {
                    _log.Info("Failed to run automatic conflict resolution", e);
                }
            }
        }