private async Task <JsonDocument> GetDocumentAsync(IAsyncDatabaseCommands databaseCommands) { var documents = await databaseCommands.GetAsync(new[] { HiLoDocumentKey, RavenKeyServerPrefix }, new string[0]).ConfigureAwait(false); if (documents.Results.Count == 2 && documents.Results[1] != null) { lastServerPrefix = documents.Results[1].Value <string>("ServerPrefix"); } else { lastServerPrefix = string.Empty; } if (documents.Results.Count == 0 || documents.Results[0] == null) { return(null); } var jsonDocument = documents.Results[0].ToJsonDocument(); foreach (var key in jsonDocument.Metadata.Keys.Where(x => x.StartsWith("@")).ToArray()) { jsonDocument.Metadata.Remove(key); } return(jsonDocument); }
///<summary> /// Ensures that the database exists, creating it if needed ///</summary> public static Task EnsureDatabaseExistsAsync(this IAsyncDatabaseCommands self, string name, bool ignoreFailures = false) { self = self.ForDefaultDatabase(); var doc = MultiDatabase.CreateDatabaseDocument(name); var docId = "Raven/Databases/" + name; return(self.GetAsync(docId) .ContinueWith(get => { if (get.Result != null) { return get; } return (Task)self.PutAsync(docId, null, doc, new RavenJObject()); }) .Unwrap() .ContinueWith(x => { if (ignoreFailures == false) { x.Wait(); // will throw on error } var observedException = x.Exception; GC.KeepAlive(observedException); })); }
private async Task <RangeValue> HandleConflictsAsync(IAsyncDatabaseCommands databaseCommands, ConflictException e, long minNextMax) { // resolving the conflict by selecting the highest number long highestMax = -1; if (e.ConflictedVersionIds.Length == 0) { throw new InvalidOperationException("Got conflict exception, but no conflicted versions", e); } foreach (var conflictedVersionId in e.ConflictedVersionIds) { var doc = await databaseCommands.GetAsync(conflictedVersionId).ConfigureAwait(false); highestMax = Math.Max(highestMax, GetMaxFromDocument(doc, minNextMax)); } await PutDocumentAsync(databaseCommands, new JsonDocument { Etag = e.Etag, Metadata = new RavenJObject(), DataAsJson = RavenJObject.FromObject(new { Max = highestMax }), Key = HiLoDocumentKey }).ConfigureAwait(false); return(await GetNextRangeAsync(databaseCommands).ConfigureAwait(false)); }
public async Task <IList <RavenMetadata> > LoadMetadataAsync(IEnumerable <string> ids) { if (ids == null) { throw new ArgumentNullException(nameof(ids)); } var result = await _commands.GetAsync(ids.Distinct().ToArray(), includes : null, metadataOnly : true); return(result.Results.Select(meta => new RavenMetadata(meta)).ToList()); }
internal static async Task AfterExecuteAsync(IAsyncDatabaseCommands asyncDatabaseCommands, string indexName, ScriptedIndexResults scripts, CancellationToken token) { var documentId = GetScriptedIndexResultsDocumentId(indexName); scripts.Id = documentId; var oldDocument = await asyncDatabaseCommands.GetAsync(documentId, token).ConfigureAwait(false); var newDocument = RavenJObject.FromObject(scripts); if (oldDocument != null && RavenJToken.DeepEquals(oldDocument.DataAsJson, newDocument)) return; await asyncDatabaseCommands.PutAsync(documentId, null, newDocument, null, token).ConfigureAwait(false); await asyncDatabaseCommands.ResetIndexAsync(indexName, token).ConfigureAwait(false); }
internal static async Task AfterExecuteAsync(IAsyncDatabaseCommands asyncDatabaseCommands, string indexName, ScriptedIndexResults scripts, CancellationToken token) { var documentId = GetScriptedIndexResultsDocumentId(indexName); scripts.Id = documentId; var oldDocument = await asyncDatabaseCommands.GetAsync(documentId, token).ConfigureAwait(false); var newDocument = RavenJObject.FromObject(scripts); if (oldDocument != null && RavenJToken.DeepEquals(oldDocument.DataAsJson, newDocument)) { return; } await asyncDatabaseCommands.PutAsync(documentId, null, newDocument, null, token).ConfigureAwait(false); await asyncDatabaseCommands.ResetIndexAsync(indexName, token).ConfigureAwait(false); }
///<summary> /// Ensures that the database exists, creating it if needed ///</summary> public static Task EnsureDatabaseExistsAsync(this IAsyncDatabaseCommands self, string name) { var doc = JObject.FromObject(new DatabaseDocument { Settings = { { "Raven/DataDir", Path.Combine("~", Path.Combine("Tenants", name)) } } }); var docId = "Raven/Databases/" + name; return(self.GetAsync(docId) .ContinueWith(get => { if (get.Result != null) { return get; } return (Task)self.PutAsync(docId, null, doc, new JObject()); }) .Unwrap()); }
///<summary> /// Ensures that the database exists, creating it if needed ///</summary> public static Task EnsureDatabaseExistsAsync(this IAsyncDatabaseCommands self, string name, bool ignoreFailures = false) { self = self.ForDefaultDatabase(); AssertValidName(name); var doc = RavenJObject.FromObject(new DatabaseDocument { Settings = { { "Raven/DataDir", Path.Combine("~", Path.Combine("Tenants", name)) } } }); doc.Remove("Id"); var docId = "Raven/Databases/" + name; return(self.GetAsync(docId) .ContinueWith(get => { if (get.Result != null) { return get; } return (Task)self.PutAsync(docId, null, doc, new RavenJObject()); }) .Unwrap() .ContinueWith(x => { if (ignoreFailures == false) { x.Wait(); // will throw on error } var observedException = x.Exception; GC.KeepAlive(observedException); })); }
private Task<JsonDocument> GetDocumentAsync(IAsyncDatabaseCommands databaseCommands) { return databaseCommands.GetAsync(new[] { HiLoDocumentKey, RavenKeyServerPrefix }, new string[0]) .ContinueWith(task => { var documents = task.Result; if (documents.Results.Count == 2 && documents.Results[1] != null) { lastServerPrefix = documents.Results[1].Value<string>("ServerPrefix"); } else { lastServerPrefix = string.Empty; } if (documents.Results.Count == 0 || documents.Results[0] == null) return (JsonDocument)null; var jsonDocument = documents.Results[0].ToJsonDocument(); foreach (var key in jsonDocument.Metadata.Keys.Where(x => x.StartsWith("@")).ToArray()) { jsonDocument.Metadata.Remove(key); } return jsonDocument; }); }
private Task<RangeValue> GetNextMaxAsyncInner(IAsyncDatabaseCommands databaseCommands) { var minNextMax = Range.Max; return GetDocumentAsync(databaseCommands) .ContinueWith(task => { try { JsonDocument document; try { document = task.Result; } catch (ConflictException e) { // resolving the conflict by selecting the highest number var highestMax = e.ConflictedVersionIds .Select(conflictedVersionId => databaseCommands.GetAsync(conflictedVersionId) .ContinueWith(t => GetMaxFromDocument(t.Result, minNextMax))) .AggregateAsync(Enumerable.Max); return highestMax .ContinueWith(t => PutDocumentAsync(databaseCommands, new JsonDocument { Etag = e.Etag, Metadata = new RavenJObject(), DataAsJson = RavenJObject.FromObject(new {Max = t.Result}), Key = HiLoDocumentKey })) .Unwrap() .ContinueWithTask(() => GetNextRangeAsync(databaseCommands)); } long min, max; if (document == null) { min = minNextMax + 1; max = minNextMax + capacity; document = new JsonDocument { Etag = Guid.Empty, // sending empty guid means - ensure the that the document does NOT exists Metadata = new RavenJObject(), DataAsJson = RavenJObject.FromObject(new {Max = max}), Key = HiLoDocumentKey }; } else { var oldMax = GetMaxFromDocument(document, minNextMax); min = oldMax + 1; max = oldMax + capacity; document.DataAsJson["Max"] = max; } return PutDocumentAsync(databaseCommands, document).WithResult(new RangeValue(min, max)); } catch (ConcurrencyException) { return GetNextMaxAsyncInner(databaseCommands); } }).Unwrap(); }
private Task <RangeValue> GetNextMaxAsyncInner(IAsyncDatabaseCommands databaseCommands) { var minNextMax = Range.Max; return(GetDocumentAsync(databaseCommands) .ContinueWith(task => { try { JsonDocument document; try { document = task.Result; } catch (ConflictException e) { // resolving the conflict by selecting the highest number var highestMax = e.ConflictedVersionIds .Select(conflictedVersionId => databaseCommands.GetAsync(conflictedVersionId) .ContinueWith(t => GetMaxFromDocument(t.Result, minNextMax))) .AggregateAsync(Enumerable.Max); return highestMax .ContinueWith(t => PutDocumentAsync(databaseCommands, new JsonDocument { Etag = e.Etag, Metadata = new RavenJObject(), DataAsJson = RavenJObject.FromObject(new { Max = t.Result }), Key = HiLoDocumentKey })) .Unwrap() .ContinueWithTask(() => GetNextRangeAsync(databaseCommands)); } long min, max; if (document == null) { min = minNextMax + 1; max = minNextMax + capacity; document = new JsonDocument { Etag = Etag.Empty, // sending empty etag means - ensure the that the document does NOT exists Metadata = new RavenJObject(), DataAsJson = RavenJObject.FromObject(new { Max = max }), Key = HiLoDocumentKey }; } else { var oldMax = GetMaxFromDocument(document, minNextMax); min = oldMax + 1; max = oldMax + capacity; document.DataAsJson["Max"] = max; } return PutDocumentAsync(databaseCommands, document).WithResult(new RangeValue(min, max)); } catch (ConcurrencyException) { return GetNextMaxAsyncInner(databaseCommands); } }).Unwrap()); }
private async Task<RangeValue> HandleConflictsAsync(IAsyncDatabaseCommands databaseCommands, ConflictException e, long minNextMax) { // resolving the conflict by selecting the highest number long highestMax = -1; if (e.ConflictedVersionIds.Length == 0) throw new InvalidOperationException("Got conflict exception, but no conflicted versions",e); foreach (var conflictedVersionId in e.ConflictedVersionIds) { var doc = await databaseCommands.GetAsync(conflictedVersionId).ConfigureAwait(false); highestMax = Math.Max(highestMax, GetMaxFromDocument(doc, minNextMax)); } await PutDocumentAsync(databaseCommands, new JsonDocument { Etag = e.Etag, Metadata = new RavenJObject(), DataAsJson = RavenJObject.FromObject(new { Max = highestMax }), Key = HiLoDocumentKey }).ConfigureAwait(false); return await GetNextRangeAsync(databaseCommands).ConfigureAwait(false); }
private static async Task HandleDatabaseInServerAsync(ServerRecord server, string databaseName, IAsyncDatabaseCommands dbCmds, IAsyncDocumentSession session) { var databaseRecord = await session.LoadAsync<DatabaseRecord>(server.Id + "/" + databaseName); if (databaseRecord == null) return; var replicationDocument = await dbCmds.GetAsync(Constants.RavenReplicationDestinations); if (replicationDocument == null) return; databaseRecord.IsReplicationEnabled = true; var document = replicationDocument.DataAsJson.JsonDeserialization<ReplicationDocument>(); databaseRecord.ReplicationDestinations = document.Destinations; var replicationStatistics = await dbCmds.Info.GetReplicationInfoAsync(); if (replicationStatistics != null) { databaseRecord.ReplicationStatistics = replicationStatistics; } // Monitor the replicated destinations foreach (var replicationDestination in databaseRecord.ReplicationDestinations) { if (replicationDestination.Disabled) continue; var url = replicationDestination.Url; var databasesIndex = url.IndexOf("/databases/", StringComparison.OrdinalIgnoreCase); if (databasesIndex > 0) { url = url.Substring(0, databasesIndex); } var replicationDestinationServer = await session.LoadAsync<ServerRecord>("serverRecords/" + ReplicationTask.EscapeDestinationName(url)); if (replicationDestinationServer == null) { replicationDestinationServer = new ServerRecord { Url = url, }; await session.StoreAsync(replicationDestinationServer); } else { if (DateTimeOffset.UtcNow - server.LastTriedToConnectAt <= TimeSpan.FromHours(1)) continue; } await FetchServerDatabasesAsync(replicationDestinationServer, session); } }
private static async Task HandleDatabaseInServerAsync(ServerRecord server, string databaseName, IAsyncDatabaseCommands dbCmds, IAsyncDocumentSession session) { var databaseRecord = await session.LoadAsync <DatabaseRecord>(server.Id + "/" + databaseName); if (databaseRecord == null) { return; } var replicationDocument = await dbCmds.GetAsync(Constants.RavenReplicationDestinations); if (replicationDocument == null) { return; } databaseRecord.IsReplicationEnabled = true; var document = replicationDocument.DataAsJson.JsonDeserialization <ReplicationDocument>(); databaseRecord.ReplicationDestinations = document.Destinations; var replicationStatistics = await dbCmds.Info.GetReplicationInfoAsync(); if (replicationStatistics != null) { databaseRecord.ReplicationStatistics = replicationStatistics; } // Monitor the replicated destinations foreach (var replicationDestination in databaseRecord.ReplicationDestinations) { if (replicationDestination.Disabled) { continue; } var url = replicationDestination.Url; var databasesIndex = url.IndexOf("/databases/", StringComparison.OrdinalIgnoreCase); if (databasesIndex > 0) { url = url.Substring(0, databasesIndex); } var replicationDestinationServer = await session.LoadAsync <ServerRecord>("serverRecords/" + ReplicationTask.EscapeDestinationName(url)); if (replicationDestinationServer == null) { replicationDestinationServer = new ServerRecord { Url = url, }; await session.StoreAsync(replicationDestinationServer); } else { if (DateTimeOffset.UtcNow - server.LastTriedToConnectAt <= TimeSpan.FromHours(1)) { continue; } } await FetchServerDatabasesAsync(replicationDestinationServer, session); } }