private void RunReplication(ReplicatorConfiguration config, int expectedErrCode, C4ErrorDomain expectedErrDomain) { Misc.SafeSwap(ref _repl, new Replicator(config)); _waitAssert = new WaitAssert(); var token = _repl.AddChangeListener((sender, args) => { _waitAssert.RunConditionalAssert(() => { VerifyChange(args, expectedErrCode, expectedErrDomain); if (config.Continuous && args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed == args.Status.Progress.Total) { ((Replicator)sender).Stop(); } return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); _repl.Start(); try { _waitAssert.WaitForResult(TimeSpan.FromSeconds(10)); } catch { _repl.Stop(); throw; } finally { _repl.RemoveChangeListener(token); } }
public void StopReplication() { if (_replicator != null) { _replicator.RemoveChangeListener(_replicatorListenerToken); _replicator.Stop(); } }
private void RemoveReplicator() { if (IsStarted) { StopReplicator(); } _repl?.RemoveChangeListener(_listenerToken); _repl?.Dispose(); }
public void TestStopContinuousReplicator() { var config = CreateConfig(true, false, true); using (var r = new Replicator(config)) { var stopWhen = new[] { ReplicatorActivityLevel.Connecting, ReplicatorActivityLevel.Busy, ReplicatorActivityLevel.Idle, ReplicatorActivityLevel.Idle }; foreach (var when in stopWhen) { var stopped = 0; var waitAssert = new WaitAssert(); var token = r.AddChangeListener((sender, args) => { waitAssert.RunConditionalAssert(() => { VerifyChange(args, 0, 0); // On Windows, at least, sometimes the connection is so fast that Connecting never gets called if ((args.Status.Activity == when || (when == ReplicatorActivityLevel.Connecting && args.Status.Activity > when)) && Interlocked.Exchange(ref stopped, 1) == 0) { WriteLine("***** Stop Replicator *****"); ((Replicator)sender).Stop(); } if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { WriteLine("Stopped!"); } return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); WriteLine("***** Start Replicator *****"); r.Start(); try { waitAssert.WaitForResult(TimeSpan.FromSeconds(5)); } finally { r.RemoveChangeListener(token); } Task.Delay(100).Wait(); } } }
private void Restart() { try { _replicator.RemoveChangeListener(_token); _replicator.Stop(); _replicator = null; _replicator.Dispose(); } catch (Exception) { } Connect(); }
private void Restart(ReplicatorStatusMessage obj) { try { _replicator.RemoveChangeListener(_token); _replicator.Stop(); _replicator.Dispose(); _replicator = null; Connect(); } catch (Exception e) { #if DEBUG #endif } }
public void TestReplicatorAndListenerOnSameDatabase() { using (var doc = new MutableDocument()) { OtherDb.Save(doc); } CreateListener(); using (var doc1 = new MutableDocument()) { Db.Save(doc1); } var target = new DatabaseEndpoint(Db); var config1 = CreateConfig(target, ReplicatorType.PushAndPull, true, sourceDb: OtherDb); var repl1 = new Replicator(config1); Database.Delete("urlepTestDb", Directory); var urlepTestDb = OpenDB("urlepTestDb"); using (var doc2 = new MutableDocument()) { urlepTestDb.Save(doc2); } var config2 = CreateConfig(_listener.LocalEndpoint(), ReplicatorType.PushAndPull, true, serverCert: _listener.TlsIdentity.Certs[0], sourceDb: urlepTestDb); var repl2 = new Replicator(config2); var wait1 = new ManualResetEventSlim(); var wait2 = new ManualResetEventSlim(); EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) => { if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed == args.Status.Progress.Total) { if (OtherDb.Count == 3 && Db.Count == 3 && urlepTestDb.Count == 3) { ((Replicator)sender).Stop(); } } else if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { if (sender == repl1) { wait1.Set(); } else { wait2.Set(); } } }; var token1 = repl1.AddChangeListener(changeListener); var token2 = repl2.AddChangeListener(changeListener); repl1.Start(); repl2.Start(); WaitHandle.WaitAll(new[] { wait1.WaitHandle, wait2.WaitHandle }, TimeSpan.FromSeconds(20)) .Should().BeTrue(); repl1.RemoveChangeListener(token1); repl2.RemoveChangeListener(token2); Db.Count.Should().Be(3, "because otherwise not all docs were received into Db"); OtherDb.Count.Should().Be(3, "because otherwise not all docs were received into OtherDb"); urlepTestDb.Count.Should().Be(3, "because otherwise not all docs were received into urlepTestDb"); repl1.Dispose(); repl2.Dispose(); wait1.Dispose(); wait2.Dispose(); urlepTestDb.Delete(); _listener.Stop(); Thread.Sleep(500); // wait for everything to stop }
public void TestStatus() { ulong maxConnectionCount = 0UL; ulong maxActiveCount = 0UL; //init and start a listener _listener = CreateListener(false); //listener is started at this point _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because no client connection has been established."); _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because no client connection has been established."); using (var doc1 = new MutableDocument()) using (var doc2 = new MutableDocument()) { doc1.SetString("name", "Sam"); Db.Save(doc1); doc2.SetString("name", "Mary"); OtherDb.Save(doc2); } var targetEndpoint = _listener.LocalEndpoint(); var config = new ReplicatorConfiguration(Db, targetEndpoint); using (var repl = new Replicator(config)) { var waitAssert = new WaitAssert(); var token = repl.AddChangeListener((sender, args) => { WriteLine($"Yeehaw {_listener.Status.ConnectionCount} / {_listener.Status.ActiveConnectionCount}"); maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount); maxActiveCount = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount); waitAssert.RunConditionalAssert(() => { return(args.Status.Activity == ReplicatorActivityLevel.Stopped); }); }); repl.Start(); while (repl.Status.Activity != ReplicatorActivityLevel.Busy) { Thread.Sleep(100); } // For some reason running on mac throws off the timing enough so that the active connection count // of 1 is never seen. So record the value right after it becomes busy. maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount); maxActiveCount = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount); try { waitAssert.WaitForResult(TimeSpan.FromSeconds(100)); } finally { repl.RemoveChangeListener(token); } } maxConnectionCount.Should().Be(1); maxActiveCount.Should().Be(1); //stop the listener _listener.Stop(); _listener.Status.ConnectionCount.Should().Be(0, "Listener's connection count should be 0 because the connection is stopped."); _listener.Status.ActiveConnectionCount.Should().Be(0, "Listener's active connection count should be 0 because the connection is stopped."); }
// Two replicators, replicates docs to the listener; validates connection status private void ValidateMultipleReplicationsTo(ReplicatorType replicatorType) { ulong maxConnectionCount = 0UL; ulong maxActiveCount = 0UL; var existingDocsInListener = _listener.Config.Database.Count; existingDocsInListener.Should().Be(1); using (var doc1 = new MutableDocument()) { Db.Save(doc1); } var target = _listener.LocalEndpoint(); var serverCert = _listener.TlsIdentity.Certs[0]; var config1 = CreateConfig(target, replicatorType, true, serverCert: serverCert, sourceDb: Db); var repl1 = new Replicator(config1); Database.Delete("urlepTestDb", Directory); var urlepTestDb = OpenDB("urlepTestDb"); using (var doc2 = new MutableDocument()) { urlepTestDb.Save(doc2); } var config2 = CreateConfig(target, replicatorType, true, serverCert: serverCert, sourceDb: urlepTestDb); var repl2 = new Replicator(config2); var wait1 = new ManualResetEventSlim(); var wait2 = new ManualResetEventSlim(); EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) => { maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount); maxActiveCount = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount); if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed == args.Status.Progress.Total) { if ((replicatorType == ReplicatorType.PushAndPull && OtherDb.Count == 3 && Db.Count == 3 && urlepTestDb.Count == 3) || (replicatorType == ReplicatorType.Pull && OtherDb.Count == 1 && Db.Count == 2 && urlepTestDb.Count == 2)) { ((Replicator)sender).Stop(); } } else if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { if (sender == repl1) { wait1.Set(); } else { wait2.Set(); } } }; var token1 = repl1.AddChangeListener(changeListener); var token2 = repl2.AddChangeListener(changeListener); repl1.Start(); repl2.Start(); while (repl1.Status.Activity != ReplicatorActivityLevel.Busy || repl2.Status.Activity != ReplicatorActivityLevel.Busy) { Thread.Sleep(100); } // For some reason running on mac throws off the timing enough so that the active connection count // of 1 is never seen. So record the value right after it becomes busy. maxConnectionCount = Math.Max(maxConnectionCount, _listener.Status.ConnectionCount); maxActiveCount = Math.Max(maxActiveCount, _listener.Status.ActiveConnectionCount); WaitHandle.WaitAll(new[] { wait1.WaitHandle, wait2.WaitHandle }, TimeSpan.FromSeconds(30)) .Should().BeTrue(); maxConnectionCount.Should().Be(2); maxActiveCount.Should().Be(2); // all data are transferred to/from if (replicatorType == ReplicatorType.PushAndPull) { _listener.Config.Database.Count.Should().Be(existingDocsInListener + 2UL); Db.Count.Should().Be(existingDocsInListener + 2UL); urlepTestDb.Count.Should().Be(existingDocsInListener + 2UL); } else if (replicatorType == ReplicatorType.Pull) { _listener.Config.Database.Count.Should().Be(1); Db.Count.Should().Be(existingDocsInListener + 1UL); urlepTestDb.Count.Should().Be(existingDocsInListener + 1UL); } repl1.RemoveChangeListener(token1); repl2.RemoveChangeListener(token2); repl1.Dispose(); repl2.Dispose(); wait1.Dispose(); wait2.Dispose(); urlepTestDb.Delete(); _listener.Stop(); Thread.Sleep(500); }