private DocumentCount GetDocumentsLeftCount(ReplicationStrategy replicationStrategy, string destinationUrl, string databaseName) { //first check the stats var localDocumentCount = database.Statistics.CountOfDocuments; var url = $"{replicationStrategy.ConnectionStringOptions.Url}/stats"; var request = requestFactory.Create(url, HttpMethods.Get, replicationStrategy.ConnectionStringOptions); var remoteDocumentCount = request.ExecuteRequest <DatabaseStatistics>().CountOfDocuments; var difference = localDocumentCount - remoteDocumentCount; if (difference > MaxDocumentsToCheck) { return(new DocumentCount { Count = difference, Type = CountType.Approximate, IsEtl = false }); } var sourcesDocument = replicationTask.GetLastReplicatedEtagFrom(replicationStrategy); if (sourcesDocument == null) { throw new InvalidOperationException($"Couldn't get last replicated etag for destination url: {destinationUrl} and database: {databaseName}"); } long count = 0; var earlyExit = new Reference <bool>(); database.TransactionalStorage.Batch(actions => { //get document count since last replicated etag var destinationId = sourcesDocument.ServerInstanceId.ToString(); count = actions.Documents.GetDocumentIdsAfterEtag( sourcesDocument.LastDocumentEtag, MaxDocumentsToCheck, WillDocumentBeReplicated(replicationStrategy, destinationId), earlyExit, database.WorkContext.CancellationToken).Count(); }); return(new DocumentCount { Count = earlyExit.Value == false ? count : Math.Max(count, difference), Type = earlyExit.Value == false ? CountType.Accurate : CountType.Approximate, IsEtl = false }); }
public override TimeTicks GetData(DocumentDatabase database, ReplicationTask task, ReplicationStrategy destination) { var sourceReplicationInformationWithBatchInformation = task.GetLastReplicatedEtagFrom(destination); if (sourceReplicationInformationWithBatchInformation == null) { return(null); } if (sourceReplicationInformationWithBatchInformation.LastModified.HasValue == false) { return(null); } return(new TimeTicks(SystemTime.UtcNow - sourceReplicationInformationWithBatchInformation.LastModified.Value)); }
public HttpResponseMessage ExplainGet(string docId) { if (string.IsNullOrEmpty(docId)) { return(GetMessageWithString("Document key is required.", HttpStatusCode.BadRequest)); } var destinationUrl = GetQueryStringValue("destinationUrl"); if (string.IsNullOrEmpty(destinationUrl)) { return(GetMessageWithString("Destination url is required.", HttpStatusCode.BadRequest)); } var databaseName = GetQueryStringValue("databaseName"); if (string.IsNullOrEmpty(databaseName)) { return(GetMessageWithString("Destination database name is required.", HttpStatusCode.BadRequest)); } var result = new ReplicationExplanationForDocument { Key = docId, Destination = new ReplicationExplanationForDocument.DestinationInformation { Url = destinationUrl, DatabaseName = databaseName } }; var destinations = ReplicationTask.GetReplicationDestinations(x => string.Equals(x.Url, destinationUrl, StringComparison.OrdinalIgnoreCase) && string.Equals(x.Database, databaseName, StringComparison.OrdinalIgnoreCase)); if (destinations == null || destinations.Length == 0) { result.Message = string.Format("Could not find replication destination for a given url ('{0}') and database ('{1}').", destinationUrl, databaseName); return(GetMessageWithObject(result)); } if (destinations.Length > 1) { result.Message = string.Format("There is more than one replication destination for a given url ('{0}') and database ('{1}').", destinationUrl, databaseName); return(GetMessageWithObject(result)); } var destination = destinations[0]; var destinationsReplicationInformationForSource = ReplicationTask.GetLastReplicatedEtagFrom(destination); if (destinationsReplicationInformationForSource == null) { result.Message = "Could not connect to destination server."; return(GetMessageWithObject(result)); } var destinationId = destinationsReplicationInformationForSource.ServerInstanceId.ToString(); result.Destination.ServerInstanceId = destinationId; result.Destination.LastDocumentEtag = destinationsReplicationInformationForSource.LastDocumentEtag; var document = Database.Documents.Get(docId, null); if (document == null) { result.Message = string.Format("Document with given key ('{0}') does not exist.", docId); return(GetMessageWithObject(result)); } result.Key = document.Key; result.Etag = document.Etag; string reason; if (destination.FilterDocuments(destinationId, document.Key, document.Metadata, out reason) == false) { result.Message = reason; return(GetMessageWithObject(result)); } reason = EtagUtil.IsGreaterThan(document.Etag, destinationsReplicationInformationForSource.LastDocumentEtag) ? "Document will be replicated." : "Document should have been replicated."; result.Message = reason; return(GetMessageWithObject(result)); }