示例#1
0
        public void Start()
        {
            var indexDefinitions = Database.Indexes.Definitions;
            var sideBySideIndexes = indexDefinitions.Where(x => x.Name.StartsWith(Constants.SideBySideIndexNamePrefix)).ToList();
            foreach (var indexDefinition in sideBySideIndexes)
            {
                var indexName = indexDefinition.Name;
                var instance = Database.IndexStorage.GetIndexInstance(indexName);
                if (instance == null)
                {
                    //probably deleted
                    continue;
                }

                var indexToAdd = new IndexToAdd
                {
                    Name = indexDefinition.Name,
                    Definition = indexDefinition,
                    Priority = instance.Priority
                };

                SetIndexReplaceInfo(indexName, indexToAdd);

                StartReplicatingSideBySideIndexAsync(indexToAdd);
            }

            Database.Notifications.OnIndexChange += OnIndexChange;
            Database.Notifications.OnDocumentChange += OnDocumentChange;

            indexReplicationTimer = Database.TimerManager.NewTimer(x => Execute(), TimeSpan.Zero, replicationFrequency);
            lastQueriedTimer = Database.TimerManager.NewTimer(x => SendLastQueried(), TimeSpan.Zero, lastQueriedFrequency);
        }
示例#2
0
        public void StartReplicatingSideBySideIndexAsync(IndexToAdd indexToAdd)
        {
            if (indexToAdd.Name.StartsWith(Constants.SideBySideIndexNamePrefix))
                indexToAdd.Name = indexToAdd.Name.Substring(Constants.SideBySideIndexNamePrefix.Length);

            sideBySideIndexesToReplicate.TryAdd(indexToAdd.Definition.IndexId, indexToAdd);

            ReplicateSideBySideIndexes();
        }
示例#3
0
        private void SetIndexReplaceInfo(string indexName, IndexToAdd indexToAdd)
        {
            var key = Constants.IndexReplacePrefix + indexName;
            var replaceDoc = Database.Documents.Get(key, null);
            if (replaceDoc == null)
                return;

            try
            {
                var indexReplaceInformation = replaceDoc.DataAsJson.JsonDeserialization<IndexReplaceDocument>();
                indexToAdd.MinimumEtagBeforeReplace = indexReplaceInformation.MinimumEtagBeforeReplace;
                indexToAdd.ReplaceTimeUtc = indexReplaceInformation.ReplaceTimeUtc;
            }
            catch (Exception)
            {
                //the index was already replaced or the document was deleted
                //anyway, we'll try to replicate this index with default settings
            }
        }
示例#4
0
        private void OnDocumentChange(DocumentDatabase db, DocumentChangeNotification notification, RavenJObject doc)
        {
            var docId = notification.Id;
            if (docId == null)
                return;

            if (docId.StartsWith(Constants.IndexReplacePrefix, StringComparison.OrdinalIgnoreCase) == false)
                return;

            if (notification.Type != DocumentChangeTypes.Put)
                return;

            var replaceIndexName = docId.Substring(Constants.IndexReplacePrefix.Length);
            var instance = Database.IndexStorage.GetIndexInstance(replaceIndexName);
            if (instance == null)
                return;

            var indexDefinition = Database.Indexes.GetIndexDefinition(replaceIndexName);
            if (indexDefinition == null)
                return;

            var indexToAdd = new IndexToAdd
            {
                Name = replaceIndexName,
                Definition = indexDefinition,
                Priority = instance.Priority,
            };

            SetIndexReplaceInfo(replaceIndexName, indexToAdd);

            StartReplicatingSideBySideIndexAsync(indexToAdd);
        }
示例#5
0
		public string[] PutIndexes(IndexToAdd[] indexesToAdd)
		{
			var createdIndexes = new List<string>();
			var prioritiesList = new List<IndexingPriority>();
			try
			{
				foreach (var indexToAdd in indexesToAdd)
				{
					var name = indexToAdd.Name;
					var definition = indexToAdd.Definition;
					var priority = indexToAdd.Priority;

					if (name == null)
						throw new ArgumentNullException("names","Names cannot contain null values");

					IsIndexNameValid(name);

					var existingIndex = IndexDefinitionStorage.GetIndexDefinition(name);

					if (existingIndex != null)
					{
						switch (existingIndex.LockMode)
						{
							case IndexLockMode.SideBySide:
								Log.Info("Index {0} not saved because it might be only updated by side-by-side index");
								throw new InvalidOperationException("Can not overwrite locked index: " + name + ". This index can be only updated by side-by-side index.");

							case IndexLockMode.LockedIgnore:
								Log.Info("Index {0} not saved because it was lock (with ignore)", name);
								continue;

							case IndexLockMode.LockedError:
								throw new InvalidOperationException("Can not overwrite locked index: " + name);
						}
					}

					name = name.Trim();

					if (name.Equals("dynamic", StringComparison.OrdinalIgnoreCase) ||
					    name.StartsWith("dynamic/", StringComparison.OrdinalIgnoreCase))
					{
						throw new ArgumentException("Cannot use index name " + name + " because it clashes with reserved dynamic index names", "name");
					}

					if (name.Contains("//"))
					{
						throw new ArgumentException("Cannot use an index with // in the name, but got: " + name, "name");
					}

					AssertAnalyzersValid(definition);

					switch (FindIndexCreationOptions(definition, ref name))
					{
						case IndexCreationOptions.Noop:
							continue;
						case IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex:
							// ensure that the code can compile
							new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
							IndexDefinitionStorage.UpdateIndexDefinitionWithoutUpdatingCompiledIndex(definition);							
							break;
						case IndexCreationOptions.Update:
							// ensure that the code can compile
							new DynamicViewCompiler(definition.Name, definition, Database.Extensions, IndexDefinitionStorage.IndexDefinitionsPath, Database.Configuration).GenerateInstance();
							DeleteIndex(name);
							break;
					}

					PutNewIndexIntoStorage(name, definition,true);

					WorkContext.ClearErrorsFor(name);

					TransactionalStorage.ExecuteImmediatelyOrRegisterForSynchronization(() => Database.Notifications.RaiseNotifications(new IndexChangeNotification
					{
						Name = name,
						Type = IndexChangeTypes.IndexAdded,
					}));

					createdIndexes.Add(name);
					prioritiesList.Add(priority);
				}

                var indexesIds = createdIndexes.Select(x => Database.IndexStorage.GetIndexInstance(x).indexId).ToArray();
                Database.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexesPriority(indexesIds, prioritiesList.ToArray()));
			
				return createdIndexes.ToArray();
			}
			catch (Exception e)
			{
			    Log.WarnException("Could not create index batch", e);
                foreach (var index in createdIndexes)
                {
                    DeleteIndex(index);
                }
				throw;
			}
		}
示例#6
0
        public SideBySideIndexInfo[] PutSideBySideIndexes(IndexToAdd[] indexesToAdd)
        {
            var createdIndexes = new List<SideBySideIndexInfo>();
            var prioritiesList = new List<IndexingPriority>();
            try
            {
                foreach (var indexToAdd in indexesToAdd)
                {
                    var originalIndexName = indexToAdd.Name.Trim();
                    var indexName = Constants.SideBySideIndexNamePrefix + originalIndexName;
                    var isSideBySide = true;

                    IndexCreationOptions? creationOptions = null;
                    //if there is no existing side by side index, we might need to update the old index
                    if (IndexDefinitionStorage.GetIndexDefinition(indexName) == null)
                    {
                        var originalIndexCreationOptions = FindIndexCreationOptions(indexToAdd.Definition, ref originalIndexName);
                        switch (originalIndexCreationOptions)
                        {
                            case IndexCreationOptions.Noop:
                                continue;
                            case IndexCreationOptions.Create:
                            case IndexCreationOptions.UpdateWithoutUpdatingCompiledIndex:
                                //cases in which we don't need to create a side by side index:
                                //1) index doesn't exist => need to create a new regular index
                                //2) there is an existing index and we need to update its definition without reindexing
                                indexName = originalIndexName;
                                isSideBySide = false;
                                creationOptions = originalIndexCreationOptions;
                                break;
                        }
                    }

                    var nameToAdd = PutIndexInternal(indexName, indexToAdd.Definition, disableIndexBeforePut: true, isUpdateBySideSide: true, creationOptions: creationOptions);
                    if (nameToAdd == null)
                        continue;

                    createdIndexes.Add(new SideBySideIndexInfo
                    {
                        OriginalName = originalIndexName,
                        Name = nameToAdd,
                        IsSideBySide = isSideBySide
                    });
                    prioritiesList.Add(indexToAdd.Priority);
                }

                var indexesIds = createdIndexes.Select(x => Database.IndexStorage.GetIndexInstance(x.Name).indexId).ToArray();
                Database.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexesPriority(indexesIds, prioritiesList.ToArray()));

                return createdIndexes.ToArray();
            }
            catch (Exception e)
            {
                Log.WarnException("Could not create index batch", e);
                foreach (var index in createdIndexes)
                {
                    DeleteIndex(index.Name);
                }
                throw;
            }
        }
示例#7
0
        public string[] PutIndexes(IndexToAdd[] indexesToAdd)
        {
            var createdIndexes = new List<string>();
            var prioritiesList = new List<IndexingPriority>();
            try
            {
                foreach (var indexToAdd in indexesToAdd)
                {
                    var nameToAdd = PutIndexInternal(indexToAdd.Name, indexToAdd.Definition, disableIndexBeforePut: true);
                    if (nameToAdd == null)
                        continue;

                    createdIndexes.Add(nameToAdd);
                    prioritiesList.Add(indexToAdd.Priority);
                }

                var indexesIds = createdIndexes.Select(x => Database.IndexStorage.GetIndexInstance(x).indexId).ToArray();
                Database.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexesPriority(indexesIds, prioritiesList.ToArray()));

                return createdIndexes.ToArray();
            }
            catch (Exception e)
            {
                Log.WarnException("Could not create index batch", e);
                foreach (var index in createdIndexes)
                {
                    DeleteIndex(index);
                }
                throw;
            }
        }
示例#8
0
        public string[] PutIndexes(IndexToAdd[] indexesToAdd, bool isReplication)
        {
            var createdIndexes = new List<string>();
            var prioritiesList = new List<IndexingPriority>();
            try
            {
                foreach (var indexToAdd in indexesToAdd)
                {
                    var nameToAdd = PutIndexInternal(indexToAdd.Name, indexToAdd.Definition, disableIndexBeforePut: true, isReplication: isReplication);
                    if (nameToAdd == null)
                        continue;

                    createdIndexes.Add(nameToAdd);
                    prioritiesList.Add(indexToAdd.Priority);
                }

                var indexesIds = createdIndexes.Select(x => Database.IndexStorage.GetIndexInstance(x).indexId).ToArray();
                Database.TransactionalStorage.Batch(accessor => accessor.Indexing.SetIndexesPriority(indexesIds, prioritiesList.ToArray()));

                for (var i = 0; i < createdIndexes.Count; i++)
                {
                    var indexName = createdIndexes[i];
                    var priority = prioritiesList[i];

                    var instance = Database.IndexStorage.GetIndexInstance(indexName);
                    if (instance == null)
                    {
                        Log.Warn("Couldn't set index priority because index named: '{0}' doesn't exist", indexName);
                        continue;
                    }

                    instance.Priority = priority;
                }

                return createdIndexes.ToArray();
            }
            catch (Exception e)
            {
                Log.WarnException("Could not create index batch", e);
                foreach (var index in createdIndexes)
                {
                    DeleteIndex(index);
                }
                throw;
            }
        }