public async Task <HttpResponseMessage> DocReplicatePost() { const int BatchSize = 512; var src = GetQueryStringValue("from"); if (string.IsNullOrEmpty(src)) { return(GetEmptyMessage(HttpStatusCode.BadRequest)); } while (src.EndsWith("/")) { src = src.Substring(0, src.Length - 1); // remove last /, because that has special meaning for Raven } if (string.IsNullOrEmpty(src)) { return(GetEmptyMessage(HttpStatusCode.BadRequest)); } var array = await ReadJsonArrayAsync(); if (ReplicationTask != null) { ReplicationTask.HandleHeartbeat(src); } using (Database.DisableAllTriggersForCurrentThread()) { string lastEtag = Etag.Empty.ToString(); var docIndex = 0; while (docIndex < array.Length) { using (Database.DocumentLock.Lock()) { Database.TransactionalStorage.Batch(actions => { for (var j = 0; j < BatchSize && docIndex < array.Length; j++, docIndex++) { var document = (RavenJObject)array[docIndex]; var metadata = document.Value <RavenJObject>("@metadata"); if (metadata[Constants.RavenReplicationSource] == null) { // not sure why, old document from when the user didn't have replication // that we suddenly decided to replicate, choose the source for that metadata[Constants.RavenReplicationSource] = RavenJToken.FromObject(src); } lastEtag = metadata.Value <string>("@etag"); var id = metadata.Value <string>("@id"); document.Remove("@metadata"); ReplicateDocument(actions, id, metadata, document, src); } SaveReplicationSource(src, lastEtag); }); } } } return(GetEmptyMessage()); }
public override void Respond(IHttpContext context) { var src = context.Request.QueryString["from"]; if (string.IsNullOrEmpty(src)) { context.SetStatusToBadRequest(); return; } while (src.EndsWith("/")) { src = src.Substring(0, src.Length - 1); // remove last /, because that has special meaning for Raven } if (string.IsNullOrEmpty(src)) { context.SetStatusToBadRequest(); return; } var array = context.ReadJsonArray(); if (ReplicationTask != null) { ReplicationTask.HandleHeartbeat(src); } using (Database.DisableAllTriggersForCurrentThread()) { Database.TransactionalStorage.Batch(actions => { string lastEtag = Guid.Empty.ToString(); foreach (RavenJObject document in array) { var metadata = document.Value <RavenJObject>("@metadata"); if (metadata[Constants.RavenReplicationSource] == null) { // not sure why, old document from when the user didn't have replication // that we suddenly decided to replicate, choose the source for that metadata[Constants.RavenReplicationSource] = RavenJToken.FromObject(src); } lastEtag = metadata.Value <string>("@etag"); var id = metadata.Value <string>("@id"); document.Remove("@metadata"); ReplicateDocument(actions, id, metadata, document, src); } var replicationDocKey = Constants.RavenReplicationSourcesBasePath + "/" + src; var replicationDocument = Database.Get(replicationDocKey, null); var lastAttachmentId = Guid.Empty; if (replicationDocument != null) { lastAttachmentId = replicationDocument.DataAsJson.JsonDeserialization <SourceReplicationInformation>(). LastAttachmentEtag; } Guid serverInstanceId; if (Guid.TryParse(context.Request.QueryString["dbid"], out serverInstanceId) == false) { serverInstanceId = Database.TransactionalStorage.Id; } Database.Put(replicationDocKey, null, RavenJObject.FromObject(new SourceReplicationInformation { Source = src, LastDocumentEtag = new Guid(lastEtag), LastAttachmentEtag = lastAttachmentId, ServerInstanceId = serverInstanceId }), new RavenJObject(), null); }); } }
public async Task <HttpResponseMessage> DocReplicatePost() { const int BatchSize = 512; var src = GetQueryStringValue("from"); var collections = GetQueryStringValue("collections"); if (string.IsNullOrEmpty(src)) { return(GetEmptyMessage(HttpStatusCode.BadRequest)); } while (src.EndsWith("/")) { src = src.Substring(0, src.Length - 1);// remove last /, because that has special meaning for Raven } if (string.IsNullOrEmpty(src)) { return(GetEmptyMessage(HttpStatusCode.BadRequest)); } var array = await ReadJsonArrayAsync().ConfigureAwait(false); if (ReplicationTask != null) { ReplicationTask.HandleHeartbeat(src); } using (Database.DisableAllTriggersForCurrentThread()) { var conflictResolvers = DocsReplicationConflictResolvers; string lastEtag = Etag.Empty.ToString(); var docIndex = 0; var retries = 0; while (retries < 3 && docIndex < array.Length) { var lastIndex = docIndex; using (Database.DocumentLock.Lock()) { Database.TransactionalStorage.Batch(actions => { for (var j = 0; j < BatchSize && docIndex < array.Length; j++, docIndex++) { var document = (RavenJObject)array[docIndex]; var metadata = document.Value <RavenJObject>("@metadata"); if (metadata[Constants.RavenReplicationSource] == null) { // not sure why, old document from when the user didn't have replication // that we suddenly decided to replicate, choose the source for that metadata[Constants.RavenReplicationSource] = RavenJToken.FromObject(src); } lastEtag = metadata.Value <string>("@etag"); var id = metadata.Value <string>("@id"); document.Remove("@metadata"); ReplicateDocument(actions, id, metadata, document, src, conflictResolvers); } SaveReplicationSource(src, lastEtag, array.Length, collections); retries = lastIndex == docIndex ? retries : 0; }); } if (lastIndex == docIndex) { if (retries == 3) { Log.Warn("Replication processing did not end up replicating any documents for 3 times in a row, stopping operation", retries); } else { Log.Warn("Replication processing did not end up replicating any documents, due to possible storage error, retry number: {0}", retries); } retries++; } } } return(GetEmptyMessage()); }