private static void PullWithFilter(Database database) { // tag::replication-pull-filter[] var url = new Uri("ws://localhost:4984/mydatabase"); var target = new URLEndpoint(url); var config = new ReplicatorConfiguration(database, target); config.PullFilter = (document, flags) => // <1> { if (document.GetString("type") == "draft") { return(false); } return(true); }; // Dispose() later var replicator = new Replicator(config); replicator.Start(); // end::replication-pull-filter[] }
private static void StartReplication() { var db = _Database; /* * This requires Sync Gateway running with the following config, or equivalent: * * { * "log":["*"], * "databases": { * "db": { * "server":"walrus:", * "users": { * "GUEST": {"disabled": false, "admin_channels": ["*"] } * } * } * } * } */ // tag::replication[] // Note: Android emulator needs to use 10.0.2.2 for localhost (10.0.3.2 for GenyMotion) var url = new Uri("ws://localhost:4984/db"); var target = new URLEndpoint(url); var config = new ReplicatorConfiguration(db, target) { ReplicatorType = ReplicatorType.Pull }; var replicator = new Replicator(config); replicator.Start(); // end::replication[] _Replicator = replicator; }
private static void PushWithFilter(Database database) { // tag::replication-push-filter[] var url = new Uri("ws://localhost:4984/mydatabase"); var target = new URLEndpoint(url); var config = new ReplicatorConfiguration(database, target); config.PushFilter = (document, flags) => { if (flags.HasFlag(DocumentFlags.Deleted)) { return(false); } return(true); }; // Dispose() later var replicator = new Replicator(config); replicator.Start(); // end::replication-push-filter[] }
public async Task TestReplicatorStopWhenClosed() { var config = CreateConfig(true, true, true); using (var repl = new Replicator(config)) { repl.Start(); while (repl.Status.Activity != ReplicatorActivityLevel.Idle) { WriteLine($"Replication status still {repl.Status.Activity}, waiting for idle..."); await Task.Delay(500); } this.Invoking(x => ReopenDB()) .ShouldThrow <CouchbaseLiteException>( "because the database cannot be closed while replication is running"); repl.Stop(); while (repl.Status.Activity != ReplicatorActivityLevel.Stopped) { WriteLine($"Replication status still {repl.Status.Activity}, waiting for stopped..."); await Task.Delay(500); } } }
private static void GettingStarted() { // # tag::getting-started[] // Get the database (and create it if it doesn't exist) var database = new Database("mydb"); // Create a new document (i.e. a record) in the database string id = null; using (var mutableDoc = new MutableDocument()) { mutableDoc.SetFloat("version", 2.0f) .SetString("type", "SDK"); // Save it to the database database.Save(mutableDoc); id = mutableDoc.Id; } // Update a document using (var doc = database.GetDocument(id)) using (var mutableDoc = doc.ToMutable()) { mutableDoc.SetString("language", "C#"); database.Save(mutableDoc); using (var docAgain = database.GetDocument(id)) { Console.WriteLine($"Document ID :: {docAgain.Id}"); Console.WriteLine($"Learning {docAgain.GetString("language")}"); } } // Create a query to fetch documents of type SDK // i.e. SELECT * FROM database WHERE type = "SDK" using (var query = QueryBuilder.Select(SelectResult.All()) .From(DataSource.Database(database)) .Where(Expression.Property("type").EqualTo(Expression.String("SDK")))) { // Run the query var result = query.Execute(); Console.WriteLine($"Number of rows :: {result.Count()}"); } // Create replicator to push and pull changes to and from the cloud var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/example_sg_db")); var replConfig = new ReplicatorConfiguration(database, targetEndpoint); // Add authentication replConfig.Authenticator = new BasicAuthenticator("john", "pass"); // Create replicator var replicator = new Replicator(replConfig); replicator.AddChangeListener((sender, args) => { if (args.Status.Error != null) { Console.WriteLine($"Error :: {args.Status.Error}"); } }); replicator.Start(); // Later, stop and dispose the replicator *before* closing/disposing the database // # end::getting-started[] }
void Start() { Database.SetLogLevel(LogDomain.All, LogLevel.Verbose); // Get the database (and create it if it doesn't exist) database = new Database(databaseName, new DatabaseConfiguration() { Directory = Path.Combine(Application.persistentDataPath, "CouchBase") }); // Create a new document (i.e. a record) in the database string id = null; using (MutableDocument mutableDoc = new MutableDocument("meta")) { mutableDoc.SetFloat("version", 2.0f) .SetString("type", "SDK"); // Save it to the database database.Save(mutableDoc); id = mutableDoc.Id; } statusLabel.text += "\n- Saved meta doc"; // Update a document using (Document doc = database.GetDocument("meta")) using (MutableDocument mutableDoc = doc.ToMutable()) { mutableDoc.SetFloat("version", 2.0f); database.Save(mutableDoc); using (Document docAgain = database.GetDocument("meta")) { Debug.Log($"Document ID :: {docAgain.Id}"); Debug.Log($"Version {docAgain.GetFloat("version")}"); statusLabel.text += $"\n- Retrieved: {docAgain.Id}"; } } // Create a query to fetch documents of type SDK // i.e. SELECT * FROM database WHERE type = "SDK" using (IWhere query = QueryBuilder.Select(SelectResult.All()) .From(DataSource.Database(database)) .Where(Expression.Property("version").EqualTo(Expression.Float(2.0f)))) { // Run the query IResultSet result = query.Execute(); int count = result.AllResults().Count; Debug.Log($"Number of rows :: {count}"); statusLabel.text += $"\n- Query result: {count}"; } #if UNITY_EDITOR Debug.LogWarning("CouchBase: In Unity Editor – Not replicating!"); return; #endif // Create replicator to push and pull changes to and from the cloud // NOTE: if Continuous is set to true, make sure to stop it and to clean up everything before exiting the application! URLEndpoint targetEndpoint = new URLEndpoint(new Uri(syncUrl)); ReplicatorConfiguration replConfig = new ReplicatorConfiguration(database, targetEndpoint) { // Add authentication Authenticator = new BasicAuthenticator(username, password), ReplicatorType = ReplicatorType.PushAndPull, Continuous = false }; // Create replicator replicator = new Replicator(replConfig); replicator.AddChangeListener((sender, args) => { if (args.Status.Error != null) { Debug.Log($"Error :: {args.Status.Error}"); } else { if (replicator.Status.Activity != ReplicatorActivityLevel.Busy && replicator.Status.Activity != ReplicatorActivityLevel.Connecting) { syncing = false; Debug.Log($"Done syncing: {replicator.Status.Activity}"); doneSyncing = true; } else { Debug.Log($"Progress: {args.Status.Progress.Completed} / {args.Status.Progress.Total}"); } } }); Debug.Log("Starting syncing..."); statusLabel.text += "\n- Starting syncing..."; replicator.Start(); syncing = true; // Later, stop and dispose the replicator *before* closing/disposing the database }
private static void GettingStarted() { // tag::getting-started[] // Get the database (and create it if it doesn't exist) var database = new Database("mydb"); // Create a new document (i.e. a record) in the database string id = null; using (var mutableDoc = new MutableDocument()) { mutableDoc.SetFloat("version", 2.0f) .SetString("type", "SDK"); // Save it to the database database.Save(mutableDoc); id = mutableDoc.Id; } // Update a document // Retrieve doc from database using (var doc = database.GetDocument(id)) // set the doc to mutable using (var mutableDoc = doc.ToMutable()) { // apply some modifications : // add a field & value mutableDoc.SetString("language", "C#"); // save the doc database.Save(mutableDoc); // retrieve again from Lite DB to check the updated doc // with the new field using (var docAgain = database.GetDocument(id)) { Console.WriteLine($"Document ID :: {docAgain.Id}"); Console.WriteLine($"Learning {docAgain.GetString("language")}"); } } // Create a query to fetch documents of type SDK // i.e. SELECT * FROM database WHERE type = "SDK" using (var query = QueryBuilder.Select(SelectResult.All()) .From(DataSource.Database(database)) .Where(Expression.Property("type").EqualTo(Expression.String("SDK")))) { // Run the query var result = query.Execute(); Console.WriteLine($"Number of rows :: {result.Count()}"); } // Create replicator to push and pull changes to and from the remote couchbase DB // Through Sync Gateway & WebSockets (ws) var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/getting-started-db")); var replConfig = new ReplicatorConfiguration(database, targetEndpoint); // Add authentication replConfig.Authenticator = new BasicAuthenticator("admin", "password"); // Create replicator (make sure to add an instance or static variable // named _Replicator) _Replicator = new Replicator(replConfig); // Manage replication error handling _Replicator.AddChangeListener((sender, args) => { if (args.Status.Error != null) { Console.WriteLine($"Error :: {args.Status.Error}"); } }); _Replicator.Start(); // Later, stop and dispose the replicator *before* closing/disposing the database // end::getting-started[] }
private void RunTwoStepContinuous(ReplicatorType type, string uid) { var listener = new MessageEndpointListener(new MessageEndpointListenerConfiguration(_otherDB, ProtocolType.ByteStream)); var server = new MockServerConnection(listener, ProtocolType.ByteStream); var config = new ReplicatorConfiguration(Db, new MessageEndpoint(uid, server, ProtocolType.ByteStream, new MockConnectionFactory(null))) { ReplicatorType = type, Continuous = true }; var replicator = new Replicator(config); replicator.Start(); Database firstSource = null; Database secondSource = null; Database firstTarget = null; Database secondTarget = null; if (type == ReplicatorType.Push) { firstSource = Db; secondSource = Db; firstTarget = _otherDB; secondTarget = _otherDB; } else if (type == ReplicatorType.Pull) { firstSource = _otherDB; secondSource = _otherDB; firstTarget = Db; secondTarget = Db; } else { firstSource = Db; secondSource = _otherDB; firstTarget = _otherDB; secondTarget = Db; } using (var mdoc = new MutableDocument("livesindb")) { mdoc.SetString("name", "db"); mdoc.SetInt("version", 1); firstSource.Save(mdoc); } var count = 0; while (replicator.Status.Progress.Completed == 0 || replicator.Status.Activity != ReplicatorActivityLevel.Idle) { Thread.Sleep(500); count++; count.Should().BeLessThan(10, "because otherwise the replicator did not advance"); } var previousCompleted = replicator.Status.Progress.Completed; firstTarget.Count.Should().Be(1); using (var savedDoc = secondSource.GetDocument("livesindb")) using (var mdoc = savedDoc.ToMutable()) { mdoc.SetInt("version", 2); secondSource.Save(mdoc); } count = 0; while (replicator.Status.Progress.Completed == previousCompleted || replicator.Status.Activity != ReplicatorActivityLevel.Idle) { Thread.Sleep(500); count++; count.Should().BeLessThan(10, "because otherwise the replicator did not advance"); } using (var savedDoc = secondTarget.GetDocument("livesindb")) { savedDoc.GetInt("version").Should().Be(2); } replicator.Stop(); while (replicator.Status.Activity != ReplicatorActivityLevel.Stopped) { Thread.Sleep(100); } replicator.Dispose(); }
public void TestP2PPassiveCloseAll() { var listener = new MessageEndpointListener(new MessageEndpointListenerConfiguration(_otherDB, ProtocolType.MessageStream)); var serverConnection1 = new MockServerConnection(listener, ProtocolType.MessageStream); var serverConnection2 = new MockServerConnection(listener, ProtocolType.MessageStream); var errorLogic = new ReconnectErrorLogic(); var config = new ReplicatorConfiguration(Db, new MessageEndpoint("p2ptest1", serverConnection1, ProtocolType.MessageStream, new MockConnectionFactory(errorLogic))) { Continuous = true }; var config2 = new ReplicatorConfiguration(Db, new MessageEndpoint("p2ptest2", serverConnection2, ProtocolType.MessageStream, new MockConnectionFactory(errorLogic))) { Continuous = true }; var replicator = new Replicator(config); replicator.Start(); var replicator2 = new Replicator(config2); replicator2.Start(); var count = 0; while (count++ < 10 && replicator.Status.Activity != ReplicatorActivityLevel.Idle && replicator2.Status.Activity != ReplicatorActivityLevel.Idle) { Thread.Sleep(500); count.Should().BeLessThan(10, "because otherwise the replicator(s) never went idle"); } errorLogic.ErrorActive = true; var closeCount = 0; listener.AddChangeListener((sender, args) => { if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { closeCount++; } }); listener.CloseAll(); count = 0; while (count++ < 10 && replicator.Status.Activity != ReplicatorActivityLevel.Stopped && replicator2.Status.Activity != ReplicatorActivityLevel.Stopped) { Thread.Sleep(500); count.Should().BeLessThan(10, "because otherwise the replicator(s) never stopped"); } count = 0; while (count++ < 10 && closeCount < 2) { Thread.Sleep(500); count.Should().BeLessThan(10, "because otherwise the listener(s) never stopped"); } replicator.Status.Error.Should() .NotBeNull("because closing the passive side creates an error on the active one"); replicator2.Status.Error.Should() .NotBeNull("because closing the passive side creates an error on the active one"); replicator.Dispose(); replicator2.Dispose(); }
public void TestP2PPassiveCloseAll() { using (var doc = new MutableDocument("test")) { doc.SetString("name", "Smokey"); Db.Save(doc); } var listener = new MessageEndpointListener(new MessageEndpointListenerConfiguration(OtherDb, ProtocolType.MessageStream)); var serverConnection1 = new MockServerConnection(listener, ProtocolType.MessageStream); var serverConnection2 = new MockServerConnection(listener, ProtocolType.MessageStream); var closeWait1 = new ManualResetEventSlim(); var closeWait2 = new ManualResetEventSlim(); var errorLogic = new ReconnectErrorLogic(); var config = new ReplicatorConfiguration(Db, new MessageEndpoint("p2ptest1", serverConnection1, ProtocolType.MessageStream, new MockConnectionFactory(errorLogic))) { Continuous = true }; var config2 = new ReplicatorConfiguration(Db, new MessageEndpoint("p2ptest2", serverConnection2, ProtocolType.MessageStream, new MockConnectionFactory(errorLogic))) { Continuous = true }; using (var replicator = new Replicator(config)) using (var replicator2 = new Replicator(config2)) { EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) => { if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { if (sender == replicator) { closeWait1.Set(); } else { closeWait2.Set(); } } }; replicator.AddChangeListener(changeListener); replicator2.AddChangeListener(changeListener); replicator.Start(); replicator2.Start(); errorLogic.ErrorActive = true; listener.CloseAll(); WaitHandle.WaitAll(new[] { closeWait1.WaitHandle, closeWait2.WaitHandle }, TimeSpan.FromSeconds(20)).Should().BeTrue(); replicator.Status.Error.Should() .NotBeNull("because closing the passive side creates an error on the active one"); replicator2.Status.Error.Should() .NotBeNull("because closing the passive side creates an error on the active one"); } closeWait1.Dispose(); closeWait2.Dispose(); }
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 }
static void Main(string[] args) { // Get the database (and create it if it doesn't exist) var database = new Database("mydb"); // Create a new document (i.e. a record) in the database string id = null; using (var mutableDoc = new MutableDocument()) { mutableDoc.SetFloat("version", 2.0f) .SetString("type", "SDK"); // Save it to the database database.Save(mutableDoc); id = mutableDoc.Id; } // Update a document using (var doc = database.GetDocument(id)) using (var mutableDoc = doc.ToMutable()) { mutableDoc.SetString("language", "python"); database.Save(mutableDoc); using (var docAgain = database.GetDocument(id)) { Console.WriteLine($"Document ID :: {docAgain.Id}"); Console.WriteLine($"Learning {docAgain.GetString("language")}"); } } // Create a query to fetch documents of type SDK // i.e. SELECT * FROM database WHERE type = "SDK" using (var query = QueryBuilder.Select(SelectResult.All()) .From(DataSource.Database(database)) .Where(Expression.Property("type").EqualTo(Expression.String("SDK")))) { // Run the query var result = query.Execute(); Console.WriteLine($"Number of rows :: {result.Count()}"); } using (var query = QueryBuilder.Select( SelectResult.Expression(Meta.ID), SelectResult.Property("language")) .From(DataSource.Database(database))) { foreach (var result in query.Execute()) { Console.WriteLine($"Document Name :: {result.GetString("language")}"); } } // Create replicator to push and pull changes to and from the cloud var targetEndpoint = new URLEndpoint(new Uri("ws://localhost:4984/getting-started-db")); var replConfig = new ReplicatorConfiguration(database, targetEndpoint); // Add authentication replConfig.Authenticator = new BasicAuthenticator("john", "pass"); // Create replicator (make sure to add an instance or static variable // named _Replicator) var _Replicator = new Replicator(replConfig); _Replicator.AddChangeListener((sender, args) => { if (args.Status.Error != null) { Console.WriteLine($"Error :: {args.Status.Error}"); } }); //Path.Combine(AppContext.BaseDirectory, "CouchbaseLite"); _Replicator.Start(); }
static int Main(string[] args) { try { if (args.Length != 3) { Console.WriteLine("Usage : SyncMonitor [userName] [password] [Url sync Gateway]"); return(1); } Couchbase.Lite.Support.NetDesktop.Activate(); Server serverInfo = new Server(); serverInfo.Login = args[0]; serverInfo.Password = args[1]; serverInfo.UrlServer = args[2]; IDataBaseGetter dataBaseGetter = new DataBaseGetter(); if (dataBaseGetter == null) { Console.WriteLine("Error when to create the local database"); return(2); } IReplicatorGetter replicatorGetter = new ReplicatorGetter(dataBaseGetter, serverInfo); Replicator replicator = replicatorGetter.Get(); IDataBaseLoader dataBaseLoader = new DataBaseLoader(dataBaseGetter); while (!Console.KeyAvailable) { if (Console.ReadKey(true).Key == ConsoleKey.I) { Console.WriteLine(dataBaseLoader.Resume()); } if (Console.ReadKey(true).Key == ConsoleKey.A) { int i = 1; List <string> acquereurs = dataBaseLoader.Acquereurs(); foreach (string nom in acquereurs) { Console.WriteLine($"{i++} {nom}"); } } if (Console.ReadKey(true).Key == ConsoleKey.R) { Console.WriteLine("Stopping the replicator"); replicator.Stop(); Console.WriteLine("Waiting 2 seconds ..."); Task.Delay(2000).Wait(); Console.WriteLine("starting the replicator"); replicator.Start(); } if (Console.ReadKey(true).Key == ConsoleKey.Escape) { break; } Task.Delay(500).Wait(); } return(0); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); return(3); } return(0); }
private void RunTwoStepContinuous(ReplicatorType type, string uid) { using (var OtherDb1 = OpenDB(OtherDb.Name)) using (var Db1 = OpenDB(Db.Name)) { var listener = new MessageEndpointListener(new MessageEndpointListenerConfiguration(OtherDb1, ProtocolType.ByteStream)); var server = new MockServerConnection(listener, ProtocolType.ByteStream); var config = new ReplicatorConfiguration(Db1, new MessageEndpoint(uid, server, ProtocolType.ByteStream, new MockConnectionFactory(null))) { ReplicatorType = type, Continuous = true }; using (var replicator = new Replicator(config)) { Database firstSource = null; Database secondSource = null; Database firstTarget = null; Database secondTarget = null; if (type == ReplicatorType.Push) { firstSource = Db1; secondSource = Db1; firstTarget = OtherDb1; secondTarget = OtherDb1; } else if (type == ReplicatorType.Pull) { firstSource = OtherDb1; secondSource = OtherDb1; firstTarget = Db1; secondTarget = Db1; } else { firstSource = Db1; secondSource = OtherDb1; firstTarget = OtherDb1; secondTarget = Db1; } replicator.Start(); using (var mdoc = new MutableDocument("livesindb")) { mdoc.SetString("name", "db"); mdoc.SetInt("version", 1); firstSource.Save(mdoc); } var count = 0; if (type != ReplicatorType.Push) { while (true) { count++; Thread.Sleep(1000); if (replicator.Status.Progress.Completed > 0 && replicator.Status.Activity == ReplicatorActivityLevel.Idle) { break; } } count.Should().BeLessThan(10, "because otherwise the replicator did not advance"); } else //when both doc updates happens on local side with push only, replicator.Status.Progress value wipe out too fast, so skip while loop { Thread.Sleep(1000); } var previousCompleted = replicator.Status.Progress.Completed; firstTarget.Count.Should().Be(1); using (var savedDoc = secondSource.GetDocument("livesindb")) using (var mdoc = savedDoc.ToMutable()) { mdoc.SetInt("version", 2); secondSource.Save(mdoc); } count = 0; if (type != ReplicatorType.Push) { while (true) { count++; Thread.Sleep(1000); if (replicator.Status.Progress.Completed > previousCompleted && replicator.Status.Activity == ReplicatorActivityLevel.Idle) { break; } } count.Should().BeLessThan(10, "because otherwise the replicator did not advance"); } else //when both doc updates happens on local side with push only, replicator.Status.Progress value wipe out too fast, so skip while loop { Thread.Sleep(1000); } using (var savedDoc = secondTarget.GetDocument("livesindb")) { savedDoc.GetInt("version").Should().Be(2); } replicator.Stop(); Thread.Sleep(100); while (true) { if (replicator.Status.Activity == ReplicatorActivityLevel.Stopped) { break; } } } } }
// 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); }
static void Main(string[] args) { // This only needs to be done once for whatever platform the executable is running // (UWP, iOS, Android, or desktop) Couchbase.Lite.Support.NetDesktop.Activate(); // create database var config = new DatabaseConfiguration(); config.ConflictResolver = new ExampleConflictResolver(); var database = new Database("my-database", config); // create document var newTask = new MutableDocument(); newTask.SetString("type", "task"); newTask.SetString("owner", "todo"); newTask.SetDate("createdAt", DateTimeOffset.UtcNow); newTask = database.Save(newTask).ToMutable(); // mutate document newTask.SetString("name", "Apples"); newTask = database.Save(newTask).ToMutable(); // typed accessors newTask.SetDate("createdAt", DateTimeOffset.UtcNow); var date = newTask.GetDate("createdAt"); // database transaction database.InBatch(() => { for (int i = 0; i < 10; i++) { using (var doc = new MutableDocument()) { doc.SetString("type", "user"); doc.SetString("name", $"user {i}"); using (var saved = database.Save(doc)) { Console.WriteLine($"saved user document {saved.GetString("name")}"); } } } }); // blob var bytes = File.ReadAllBytes("avatar.jpg"); var blob = new Blob("image/jpg", bytes); newTask.SetBlob("avatar", blob); newTask = database.Save(newTask).ToMutable(); var taskBlob = newTask.GetBlob("avatar"); var data = taskBlob.Content; newTask.Dispose(); // query var query = QueryBuilder.Select(SelectResult.Expression(Meta.ID)) .From(DataSource.Database(database)) .Where(Expression.Property("type").EqualTo(Expression.String("user")) .And(Expression.Property("admin").EqualTo(Expression.Boolean(false)))); var rows = query.Execute(); foreach (var row in rows) { Console.WriteLine($"doc ID :: ${row.GetString(0)}"); } // live query query.AddChangeListener((sender, e) => { Console.WriteLine($"Number of rows :: {e.Results.Count()}"); }); using (var newDoc = new MutableDocument()) { newDoc.SetString("type", "user"); newDoc.SetBoolean("admin", false); database.Save(newDoc); } // fts example // insert documents var tasks = new[] { "buy groceries", "play chess", "book travels", "buy museum tickets" }; foreach (string task in tasks) { using (var doc = new MutableDocument()) { doc.SetString("type", "task").SetString("name", task); // Chaining is possible database.Save(doc); } } // create Index var index = IndexBuilder.FullTextIndex(FullTextIndexItem.Property("name")); database.CreateIndex("byName", index); using (var ftsQuery = QueryBuilder.Select(SelectResult.Expression(Meta.ID).As("id")) .From(DataSource.Database(database)) .Where(FullTextExpression.Index("byName").Match("'buy'"))) { var ftsRows = ftsQuery.Execute(); foreach (var row in ftsRows) { var doc = database.GetDocument(row.GetString("id")); // Use alias instead of index Console.WriteLine( $"document properties {JsonConvert.SerializeObject(doc.ToDictionary(), Formatting.Indented)}"); } } // create conflict /* * 1. Create a document twice with the same ID (the document will have two conflicting revisions). * 2. Upon saving the second revision, the ExampleConflictResolver's resolve method is called. * The `theirs` ReadOnlyDocument in the conflict resolver represents the current rev and `mine` is what's being saved. * 3. Read the document after the second save operation and verify its property is as expected. * The conflict resolver will have deleted the obsolete revision. */ using (var theirs = new MutableDocument("buzz")) using (var mine = new MutableDocument("buzz")) { theirs.SetString("status", "theirs"); mine.SetString("status", "mine"); database.Save(theirs); database.Save(mine); } var conflictResolverResult = database.GetDocument("buzz"); Console.WriteLine($"conflictResolverResult doc.status ::: {conflictResolverResult.GetString("status")}"); // replication (Note: Linux / Mac requires .NET Core 2.0+ due to // https://github.com/dotnet/corefx/issues/8768) /* * Tested with SG 1.5 https://www.couchbase.com/downloads * Config file: * { * "databases": { * "db": { * "server":"walrus:", * "users": { * "GUEST": {"disabled": false, "admin_channels": ["*"]} * }, * "unsupported": { * "replicator_2":true * } * } * } * } */ var url = new Uri("ws://localhost:4984/db"); var replConfig = new ReplicatorConfiguration(database, new URLEndpoint(url)); var replication = new Replicator(replConfig); replication.Start(); // replication change listener replication.AddChangeListener((sender, e) => { if (e.Status.Activity == ReplicatorActivityLevel.Stopped) { Console.WriteLine("Replication has completed."); } }); Console.ReadLine(); // This is important to do because otherwise the native connection // won't be released until the next garbage collection query.Dispose(); database.Dispose(); }
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."); }
// Exception thrown at 0x00007FFE3090A799 in dotnet.exe: Microsoft C++ exception: EEFileLoadException at memory location 0x000000C288E79D88. //Exception thrown at 0x00007FFE3090A799 in dotnet.exe: Microsoft C++ exception: [rethrow] at memory location 0x0000000000000000. //[Fact] uwp public void TestP2PPassiveCloseAll() { using (var doc = new MutableDocument("test")) { doc.SetString("name", "Smokey"); Db.Save(doc); } var listener = new MessageEndpointListener(new MessageEndpointListenerConfiguration(OtherDb, ProtocolType.MessageStream)); var serverConnection1 = new MockServerConnection(listener, ProtocolType.MessageStream); var serverConnection2 = new MockServerConnection(listener, ProtocolType.MessageStream); var closeWait1 = new ManualResetEventSlim(); var closeWait2 = new ManualResetEventSlim(); var errorLogic = new ReconnectErrorLogic(); var config = new ReplicatorConfiguration(Db, new MessageEndpoint("p2ptest1", serverConnection1, ProtocolType.MessageStream, new MockConnectionFactory(errorLogic))) { Continuous = true }; var config2 = new ReplicatorConfiguration(Db, new MessageEndpoint("p2ptest2", serverConnection2, ProtocolType.MessageStream, new MockConnectionFactory(errorLogic))) { Continuous = true }; using (var replicator = new Replicator(config)) using (var replicator2 = new Replicator(config2)) { replicator.Start(); replicator2.Start(); var count = 0; while (count++ < 15 && replicator.Status.Activity != ReplicatorActivityLevel.Idle && replicator2.Status.Activity != ReplicatorActivityLevel.Idle) { Thread.Sleep(500); count.Should().BeLessThan(15, "because otherwise the replicator(s) never went idle"); } errorLogic.ErrorActive = true; listener.AddChangeListener((sender, args) => { if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { if (args.Connection == serverConnection1) { closeWait1.Set(); } else { closeWait2.Set(); } } }); var connection = listener.Connections; listener.CloseAll(); count = 0; while (count++ < 10 && replicator.Status.Activity != ReplicatorActivityLevel.Stopped && replicator2.Status.Activity != ReplicatorActivityLevel.Stopped) { Thread.Sleep(500); count.Should().BeLessThan(10, "because otherwise the replicator(s) never stopped"); } closeWait1.Wait(TimeSpan.FromSeconds(5)).Should() .BeTrue("because otherwise the first listener did not stop"); closeWait2.Wait(TimeSpan.FromSeconds(5)).Should() .BeTrue("because otherwise the second listener did not stop"); replicator.Status.Error.Should() .NotBeNull("because closing the passive side creates an error on the active one"); replicator2.Status.Error.Should() .NotBeNull("because closing the passive side creates an error on the active one"); } }
private void WithActiveReplicationsAndURLEndpointListener(bool isCloseNotDelete) { var waitIdleAssert1 = new ManualResetEventSlim(); var waitIdleAssert2 = new ManualResetEventSlim(); var waitStoppedAssert1 = new ManualResetEventSlim(); var waitStoppedAssert2 = new ManualResetEventSlim(); using (var doc = new MutableDocument()) { OtherDb.Save(doc); } _listener = CreateListener(); _listener.Config.Database.ActiveStoppables.Count.Should().Be(1); 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); EventHandler <ReplicatorStatusChangedEventArgs> changeListener = (sender, args) => { if (args.Status.Activity == ReplicatorActivityLevel.Idle && args.Status.Progress.Completed == args.Status.Progress.Total) { if (sender == repl1) { waitIdleAssert1.Set(); } else { waitIdleAssert2.Set(); } } else if (args.Status.Activity == ReplicatorActivityLevel.Stopped) { if (sender == repl1) { waitStoppedAssert1.Set(); } else { waitStoppedAssert2.Set(); } } }; repl1.AddChangeListener(changeListener); repl2.AddChangeListener(changeListener); repl1.Start(); repl2.Start(); WaitHandle.WaitAll(new[] { waitIdleAssert1.WaitHandle, waitIdleAssert2.WaitHandle }, _timeout) .Should().BeTrue(); OtherDb.ActiveStoppables.Count.Should().Be(2); urlepTestDb.ActiveStoppables.Count.Should().Be(1); if (isCloseNotDelete) { urlepTestDb.Close(); OtherDb.Close(); } else { urlepTestDb.Delete(); OtherDb.Delete(); } OtherDb.ActiveStoppables.Count.Should().Be(0); urlepTestDb.ActiveStoppables.Count.Should().Be(0); OtherDb.IsClosedLocked.Should().Be(true); urlepTestDb.IsClosedLocked.Should().Be(true); WaitHandle.WaitAll(new[] { waitStoppedAssert1.WaitHandle, waitStoppedAssert2.WaitHandle }, TimeSpan.FromSeconds(20)) .Should().BeTrue(); waitIdleAssert1.Dispose(); waitIdleAssert2.Dispose(); waitStoppedAssert1.Dispose(); waitStoppedAssert2.Dispose(); Thread.Sleep(500); }
public static void Main(string[] args) { Console.CancelKeyPress += new ConsoleCancelEventHandler(Cancelled); if (args.Length == 0) { args = new string[7]; //storage account locating configuration of given container args[0] = "dbtsouthstorage"; // "devstoreaccount1"; // container name args[1] = "testcontainer"; // the result folder name args[2] = "folder1"; //sleep time between ticks in milliseconds. args[3] = "90000"; //interval between configuration args[4] = "2"; //duration of experiment in ticks args[5] = "24"; //start tick for configuration args[6] = "1"; } configurationSite = args[0]; containerName = args[1]; resultFileFolderName = args[2]; sleepTimeBetweenTicks = Int32.Parse(args[3]); ticksBetweenConfigurations = Int32.Parse(args[4]); experimentDurationInTicks = Int32.Parse(args[5]); startTickOfConfiguration = Int32.Parse(args[6]); Dictionary <string, CloudStorageAccount> acounts = Account.GetStorageAccounts(true); acounts.Remove("devstoreaccount1"); ClientRegistry.Init(acounts, Account.GetStorageAccounts(true)[configurationSite]); ReplicaConfiguration configuration = ClientRegistry.GetConfiguration(containerName, false); Configurator conf = new Configurator(containerName); #region replicator Replicator replicator = new Replicator(containerName); replicator.Start(); #endregion #region configurator List <ConfigurationConstraint> constraints = new List <ConfigurationConstraint>(); //constraints.Add(new LocationConstraint(containerName, "dbteastasiastorage", LocationConstraintType.Replicate)); constraints.Add(new ReplicationFactorConstraint(containerName, configuration, 1, 2)); DateTime startTime = DateTime.Now; Thread.Sleep(startTickOfConfiguration * sleepTimeBetweenTicks); while (DateTime.Now.Subtract(startTime).TotalMilliseconds < (experimentDurationInTicks * sleepTimeBetweenTicks)) { try { configuration = ClientRegistry.GetConfiguration(containerName, false); Console.WriteLine("Starting to reconfigure. Current Epoch: " + configuration.Epoch); conf.Configure(ClientRegistry.GetConfigurationAccount(), configuration.Epoch, configuration, constraints); Console.WriteLine(Configurator.Logs); Console.WriteLine(">>>>>>>>>>> Finished. Current Epoch: " + configuration.Epoch + "<<<<<<<<<<<<<<<<"); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); } Thread.Sleep(ticksBetweenConfigurations * sleepTimeBetweenTicks); } #endregion return; }