Exemplo n.º 1
0
        private JsonDocumentsToReplicate GetJsonDocuments(SourceReplicationInformation destinationsReplicationInformationForSource, ReplicationStrategy destination)
        {
            var result = new JsonDocumentsToReplicate();

            try
            {
                var destinationId = destinationsReplicationInformationForSource.ServerInstanceId.ToString();

                docDb.TransactionalStorage.Batch(actions =>
                {
                    int docsSinceLastReplEtag = 0;
                    List <JsonDocument> docsToReplicate;
                    List <JsonDocument> filteredDocsToReplicate;
                    result.LastEtag = destinationsReplicationInformationForSource.LastDocumentEtag;
                    while (true)
                    {
                        docsToReplicate = GetDocsToReplicate(actions, result);

                        filteredDocsToReplicate =
                            docsToReplicate
                            .Where(document =>
                        {
                            var info = docDb.GetRecentTouchesFor(document.Key);
                            if (info != null)
                            {
                                if (Etag.IsGreaterThan(info.PreTouchEtag, result.LastEtag) == false)
                                {
                                    return(false);
                                }
                            }

                            return(destination.FilterDocuments(destinationId, document.Key, document.Metadata));
                        })
                            .ToList();

                        docsSinceLastReplEtag += docsToReplicate.Count;
                        result.CountOfFilteredDocumentsWhichAreSystemDocuments += docsToReplicate.Count(doc => destination.IsSystemDocumentId(doc.Key));

                        if (docsToReplicate.Count > 0)
                        {
                            var lastDoc = docsToReplicate.Last();
                            Debug.Assert(lastDoc.Etag != null);
                            result.LastEtag = lastDoc.Etag.Value;
                            if (lastDoc.LastModified.HasValue)
                            {
                                result.LastLastModified = lastDoc.LastModified.Value;
                            }
                        }

                        if (docsToReplicate.Count == 0 || filteredDocsToReplicate.Count != 0)
                        {
                            break;
                        }

                        log.Debug("All the docs were filtered, trying another batch from etag [>{0}]", result.LastEtag);
                    }

                    log.Debug(() =>
                    {
                        if (docsSinceLastReplEtag == 0)
                        {
                            return(string.Format("No documents to replicate to {0} - last replicated etag: {1}", destination,
                                                 destinationsReplicationInformationForSource.LastDocumentEtag));
                        }

                        if (docsSinceLastReplEtag == filteredDocsToReplicate.Count)
                        {
                            return(string.Format("Replicating {0} docs [>{1}] to {2}.",
                                                 docsSinceLastReplEtag,
                                                 destinationsReplicationInformationForSource.LastDocumentEtag,
                                                 destination));
                        }

                        var diff = docsToReplicate.Except(filteredDocsToReplicate).Select(x => x.Key);
                        return(string.Format("Replicating {1} docs (out of {0}) [>{4}] to {2}. [Not replicated: {3}]",
                                             docsSinceLastReplEtag,
                                             filteredDocsToReplicate.Count,
                                             destination,
                                             string.Join(", ", diff),
                                             destinationsReplicationInformationForSource.LastDocumentEtag));
                    });

                    result.Documents = new RavenJArray(filteredDocsToReplicate
                                                       .Select(x =>
                    {
                        DocumentRetriever.EnsureIdInMetadata(x);
                        return(x);
                    })
                                                       .Select(x => x.ToJson()));
                });
            }
            catch (Exception e)
            {
                log.WarnException("Could not get documents to replicate after: " + destinationsReplicationInformationForSource.LastDocumentEtag, e);
            }
            return(result);
        }