Пример #1
0
        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);
        }
Пример #2
0
        ///<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);
            }));
        }
Пример #3
0
        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));
        }
Пример #4
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        ///<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());
        }
Пример #8
0
        ///<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);
            }));
        }
Пример #9
0
		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;
				});
		}
Пример #10
0
		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();
		}
Пример #11
0
        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());
        }
Пример #12
0
	    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);
	    }
Пример #13
0
		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);
			}
		}
Пример #14
0
        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);
            }
        }