public void TestSequenceMap() { var map = new SequenceMap(); Assert.AreEqual(0, map.GetCheckpointedSequence()); Assert.AreEqual(null, map.GetCheckpointedValue()); Assert.IsTrue(map.IsEmpty()); Assert.AreEqual(1, map.AddValue("one")); Assert.AreEqual(0, map.GetCheckpointedSequence()); Assert.AreEqual(null, map.GetCheckpointedValue()); Assert.IsTrue(!map.IsEmpty()); Assert.AreEqual(2, map.AddValue("two")); Assert.AreEqual(0, map.GetCheckpointedSequence()); Assert.AreEqual(null, map.GetCheckpointedValue()); Assert.AreEqual(3, map.AddValue("three")); Assert.AreEqual(0, map.GetCheckpointedSequence()); Assert.AreEqual(null, map.GetCheckpointedValue()); map.RemoveSequence(2); Assert.AreEqual(0, map.GetCheckpointedSequence()); Assert.AreEqual(null, map.GetCheckpointedValue()); map.RemoveSequence(1); Assert.AreEqual(2, map.GetCheckpointedSequence()); Assert.AreEqual("two", map.GetCheckpointedValue()); Assert.AreEqual(4, map.AddValue("four")); Assert.AreEqual(2, map.GetCheckpointedSequence()); Assert.AreEqual("two", map.GetCheckpointedValue()); map.RemoveSequence(3); Assert.AreEqual(3, map.GetCheckpointedSequence()); Assert.AreEqual("three", map.GetCheckpointedValue()); map.RemoveSequence(4); Assert.AreEqual(4, map.GetCheckpointedSequence()); Assert.AreEqual("four", map.GetCheckpointedValue()); Assert.IsTrue(map.IsEmpty()); }
/// <summary>Process a bunch of remote revisions from the _changes feed at once</summary> internal override void ProcessInbox(RevisionList inbox) { Debug.Assert(inbox != null); // Ask the local database which of the revs are not known to it: //Log.w(Database.TAG, String.format("%s: Looking up %s", this, inbox)); var lastInboxSequence = ((PulledRevision)inbox[inbox.Count - 1]).GetRemoteSequenceID (); var total = ChangesCount - inbox.Count; if (!LocalDatabase.FindMissingRevisions(inbox)) { Log.W(Tag, string.Format("{0} failed to look up local revs", this)); inbox = null; } //introducing this to java version since inbox may now be null everywhere var inboxCount = 0; if (inbox != null) { inboxCount = inbox.Count; } ChangesCount = total + inboxCount; if (inboxCount == 0) { // Nothing to do. Just bump the lastSequence. Log.W(Tag, string.Format("{0} no new remote revisions to fetch", this)); var seq = pendingSequences.AddValue(lastInboxSequence); pendingSequences.RemoveSequence(seq); LastSequence = pendingSequences.GetCheckpointedValue(); return; } Log.V(Tag, this + " fetching " + inboxCount + " remote revisions..."); //Log.v(Database.TAG, String.format("%s fetching remote revisions %s", this, inbox)); // Dump the revs into the queue of revs to pull from the remote db: lock (locker) { if (revsToPull == null) { revsToPull = new AList <RevisionInternal> (200); } for (int i = 0; i < inbox.Count; i++) { var rev = (PulledRevision)inbox [i]; // FIXME add logic here to pull initial revs in bulk rev.SetSequence(pendingSequences.AddValue(rev.GetRemoteSequenceID())); revsToPull.AddItem(rev); } } PullRemoteRevisions(); }
internal override void BeginReplicating() { Log.To.Sync.I(TAG, "{2} will use MaxOpenHttpConnections({0}), MaxRevsToGetInBulk({1})", ReplicationOptions.MaxOpenHttpConnections, ReplicationOptions.MaxRevsToGetInBulk, this); if (_downloadsToInsert == null) { const int capacity = INBOX_CAPACITY * 2; TimeSpan delay = TimeSpan.FromSeconds(1); _downloadsToInsert = new Batcher <RevisionInternal>(WorkExecutor, capacity, delay, InsertDownloads); } if (_pendingSequences == null) { _pendingSequences = new SequenceMap(); if (LastSequence != null) { // Prime _pendingSequences so its checkpointedValue will reflect the last known seq: var seq = _pendingSequences.AddValue(LastSequence); _pendingSequences.RemoveSequence(seq); Debug.Assert((_pendingSequences.GetCheckpointedValue().Equals(LastSequence))); } } _caughtUp = false; StartChangeTracker(); }
internal override void BeginReplicating() { Log.D(TAG, string.Format("Using MaxOpenHttpConnections({0}), MaxRevsToGetInBulk({1})", ManagerOptions.Default.MaxOpenHttpConnections, ManagerOptions.Default.MaxRevsToGetInBulk)); if (_downloadsToInsert == null) { const int capacity = INBOX_CAPACITY * 2; const int delay = 1000; _downloadsToInsert = new Batcher <RevisionInternal>(WorkExecutor, capacity, delay, InsertDownloads); } if (_pendingSequences == null) { _pendingSequences = new SequenceMap(); if (LastSequence != null) { // Prime _pendingSequences so its checkpointedValue will reflect the last known seq: var seq = _pendingSequences.AddValue(LastSequence); _pendingSequences.RemoveSequence(seq); Debug.Assert((_pendingSequences.GetCheckpointedValue().Equals(LastSequence))); } } StartChangeTracker(); }
internal override void BeginReplicating() { Log.D(Tag, string.Format("Using MaxOpenHttpConnections({0}), MaxRevsToGetInBulk({1})", ManagerOptions.Default.MaxOpenHttpConnections, ManagerOptions.Default.MaxRevsToGetInBulk)); if (downloadsToInsert == null) { const int capacity = 200; const int delay = 1000; downloadsToInsert = new Batcher <RevisionInternal> (WorkExecutor, capacity, delay, InsertDownloads); } if (pendingSequences == null) { pendingSequences = new SequenceMap(); if (LastSequence != null) { // Prime _pendingSequences so its checkpointedValue will reflect the last known seq: var seq = pendingSequences.AddValue(LastSequence); pendingSequences.RemoveSequence(seq); Debug.Assert((pendingSequences.GetCheckpointedValue().Equals(LastSequence))); } } Log.D(Tag, "starting ChangeTracker with since = " + LastSequence); var mode = Continuous ? ChangeTrackerMode.LongPoll : ChangeTrackerMode.OneShot; changeTracker = new ChangeTracker(RemoteUrl, mode, LastSequence, true, this, WorkExecutor); changeTracker.Authenticator = Authenticator; if (Filter != null) { changeTracker.SetFilterName(Filter); if (FilterParams != null) { changeTracker.SetFilterParams(FilterParams.ToDictionary(kvp => kvp.Key, kvp => (Object)kvp.Value)); } } if (!continuous) { Log.D(Tag, "BeginReplicating() calling asyncTaskStarted()"); AsyncTaskStarted(); } changeTracker.UsePost = CheckServerCompatVersion("0.93"); changeTracker.Start(); }
public override void BeginReplicating() { if (downloadsToInsert == null) { int capacity = 200; int delay = 1000; downloadsToInsert = new Batcher <RevisionInternal>(workExecutor, capacity, delay, new _BatchProcessor_131(this)); } if (pendingSequences == null) { pendingSequences = new SequenceMap(); if (GetLastSequence() != null) { // Prime _pendingSequences so its checkpointedValue will reflect the last known seq: long seq = pendingSequences.AddValue(GetLastSequence()); pendingSequences.RemoveSequence(seq); System.Diagnostics.Debug.Assert((pendingSequences.GetCheckpointedValue().Equals(GetLastSequence ()))); } } Log.W(Log.TagSync, "%s: starting ChangeTracker with since=%s", this, lastSequence ); changeTracker = new ChangeTracker(remote, continuous ? ChangeTracker.ChangeTrackerMode .LongPoll : ChangeTracker.ChangeTrackerMode.OneShot, true, lastSequence, this); changeTracker.SetAuthenticator(GetAuthenticator()); Log.W(Log.TagSync, "%s: started ChangeTracker %s", this, changeTracker); if (filterName != null) { changeTracker.SetFilterName(filterName); if (filterParams != null) { changeTracker.SetFilterParams(filterParams); } } changeTracker.SetDocIDs(documentIDs); changeTracker.SetRequestHeaders(requestHeaders); if (!continuous) { Log.V(Log.TagSync, "%s | %s: beginReplicating() calling asyncTaskStarted()", this , Sharpen.Thread.CurrentThread()); AsyncTaskStarted(); } changeTracker.SetUsePOST(ServerIsSyncGatewayVersion("0.93")); changeTracker.Start(); }
/// <summary>Process a bunch of remote revisions from the _changes feed at once</summary> internal override void ProcessInbox(RevisionList inbox) { if (!online) { Log.V(Tag, "Offline, so skipping inbox process"); return; } Debug.Assert(inbox != null); if (!canBulkGet) { canBulkGet = CheckServerCompatVersion("0.81"); } // Ask the local database which of the revs are not known to it: var lastInboxSequence = ((PulledRevision)inbox[inbox.Count - 1]).GetRemoteSequenceID(); var numRevisionsRemoved = 0; try { // findMissingRevisions is the local equivalent of _revs_diff. it looks at the // array of revisions in inbox and removes the ones that already exist. So whatever's left in inbox // afterwards are the revisions that need to be downloaded. numRevisionsRemoved = LocalDatabase.FindMissingRevisions(inbox); } catch (Exception e) { Log.E(Tag, "Failed to look up local revs", e); inbox = null; } //introducing this to java version since inbox may now be null everywhere var inboxCount = 0; if (inbox != null) { inboxCount = inbox.Count; } if (numRevisionsRemoved > 0) { Log.V(Tag, "processInbox() setting changesCount to: " + (ChangesCount - numRevisionsRemoved)); SafeAddToChangesCount(-numRevisionsRemoved); } if (inboxCount == 0) { // Nothing to do. Just bump the lastSequence. Log.W(Tag, string.Format("{0} no new remote revisions to fetch", this)); var seq = pendingSequences.AddValue(lastInboxSequence); pendingSequences.RemoveSequence(seq); LastSequence = pendingSequences.GetCheckpointedValue(); return; } Log.V(Tag, "fetching " + inboxCount + " remote revisions..."); // Dump the revs into the queue of revs to pull from the remote db: lock (locker) { int numBulked = 0; for (int i = 0; i < inbox.Count; i++) { var rev = (PulledRevision)inbox [i]; //TODO: add support for rev isConflicted if (canBulkGet || (rev.GetGeneration() == 1 && !rev.IsDeleted())) { // &&!rev.isConflicted) //optimistically pull 1st-gen revs in bulk if (bulkRevsToPull == null) { bulkRevsToPull = new List <RevisionInternal>(100); } bulkRevsToPull.AddItem(rev); ++numBulked; } else { QueueRemoteRevision(rev); } rev.SetSequence(pendingSequences.AddValue(rev.GetRemoteSequenceID())); } } PullRemoteRevisions(); }
protected internal override void ProcessInbox(RevisionList inbox) { if (canBulkGet == null) { canBulkGet = ServerIsSyncGatewayVersion("0.81"); } // Ask the local database which of the revs are not known to it: string lastInboxSequence = ((PulledRevision)inbox[inbox.Count - 1]).GetRemoteSequenceID (); int numRevisionsRemoved = 0; try { // findMissingRevisions is the local equivalent of _revs_diff. it looks at the // array of revisions in ‘inbox’ and removes the ones that already exist. So whatever’s left in ‘inbox’ // afterwards are the revisions that need to be downloaded. numRevisionsRemoved = db.FindMissingRevisions(inbox); } catch (SQLException e) { Log.E(Log.TagSync, string.Format("%s failed to look up local revs", this), e); inbox = null; } //introducing this to java version since inbox may now be null everywhere int inboxCount = 0; if (inbox != null) { inboxCount = inbox.Count; } if (numRevisionsRemoved > 0) { Log.V(Log.TagSync, "%s: processInbox() setting changesCount to: %s", this, GetChangesCount () - numRevisionsRemoved); // May decrease the changesCount, to account for the revisions we just found out we don’t need to get. AddToChangesCount(-1 * numRevisionsRemoved); } if (inboxCount == 0) { // Nothing to do. Just bump the lastSequence. Log.W(Log.TagSync, "%s no new remote revisions to fetch", this); long seq = pendingSequences.AddValue(lastInboxSequence); pendingSequences.RemoveSequence(seq); SetLastSequence(pendingSequences.GetCheckpointedValue()); return; } Log.V(Log.TagSync, "%s: fetching %s remote revisions...", this, inboxCount); // Dump the revs into the queue of revs to pull from the remote db: lock (this) { int numBulked = 0; for (int i = 0; i < inbox.Count; i++) { PulledRevision rev = (PulledRevision)inbox[i]; //TODO: add support for rev isConflicted if (canBulkGet || (rev.GetGeneration() == 1 && !rev.IsDeleted())) { // &&!rev.isConflicted) //optimistically pull 1st-gen revs in bulk if (bulkRevsToPull == null) { bulkRevsToPull = new AList <RevisionInternal>(100); } bulkRevsToPull.AddItem(rev); ++numBulked; } else { QueueRemoteRevision(rev); } rev.SetSequence(pendingSequences.AddValue(rev.GetRemoteSequenceID())); } } PullRemoteRevisions(); }