Developer forum

Forum » Development » Building Repository Indexes Manually

Building Repository Indexes Manually

Anders Ditlevsen
Anders Ditlevsen
Reply

Hi

We have a project where we build the index of a repository used for news items manually. The rebuilding code is run when a item of the type "news item" is saved. To avoid building both instances of the index at the same time, we have used a check to avoid this which is as follows:

public static void RebuildIndex(string repoName, string indexName, string build)
        {
            if (!string.IsNullOrEmpty(indexName) && !indexName.ToLower().EndsWith(".index"))
            {
                indexName = string.Format("{0}.index", indexName);
            }
            // Get the current IIndexService from the ServiceLocator
            Task.Factory.StartNew(() =>
            {

                var indexService = ServiceLocator.Current.GetInstance<IIndexService>();

                // Build the specified index using the IIndexService
                var index = indexService.LoadIndex(repoName, indexName);
                var currentInstance = index.GetInstance();
                foreach (var instanceName in index.Instances.Keys)
                {
                    if (instanceName == currentInstance.Name)
                        continue;
                    indexService.BuildIndex(repoName, indexName, instanceName, build);
                }
                var startTime = DateTime.Now;
                while (true)
                {
                    var tasks = indexService.GetActiveBuildTasks(index);
                    if (!tasks.Any() || DateTime.Now.Subtract(startTime).TotalMinutes >= 45)
                        break;

                    Task.WaitAll(new[] { Task.Delay(5000) });
                }
                RebuildIndexCurrentInstance(repoName, indexName, build);
            });
        }

 

Is this check OK, to stop both indexes from being locked at the same time, even if its only for miliseconds?

 


Replies

 
Nicolai Pedersen
Reply
This post has been marked as an answer

Hi Anders

It looks ok... But any reason you do not call IndexHelper.BuildIndexInstances?

It will do the same thing I think...

This is the code from our BuildIndexInstances method.

public static void BuildIndexInstances(string repository, string indexName, string buildName)
        {
            IIndexService indexService = ServiceLocator.Current.GetInstance<IIndexService>();
            IIndex index = indexService.LoadIndex(repository, indexName);
            // Verify that the Index exists
            if (index != null)
            {
                // Verify that a current instance can be found
                var currentInstance = index.GetInstance();
                if (currentInstance != null)
                {
                    // Looping though all instances an building all other than the current
                    var buildStarted = false;
                    foreach (var instance in index.Instances.Keys)
                    {
                        if (instance == currentInstance.Name)
                            continue;

                        buildStarted = true;
                        indexService.BuildIndex(repository, index.Name, instance, buildName);
                    }

                    // If any builds were started, make sure that the tasks are registered
                    // If they were not registered within 5 seconds, we continue
                    if (buildStarted)
                    {
                        var stopwatch = Stopwatch.StartNew();
                        while (!indexService.GetActiveBuildTasks(index).Any() && stopwatch.ElapsedMilliseconds < 5000)
                        {
                            Wait(250);
                        }
                        stopwatch.Stop();
                    }

                    // Waiting for the build tasks to complete, or 45 minutes to elapse
                    var startTime = DateTime.Now;
                    while (true)
                    {
                        var tasks = indexService.GetActiveBuildTasks(index);
                        if (!tasks.Any() || DateTime.Now.Subtract(startTime).TotalMinutes >= 45)
                            break;

                        Wait();
                    }

                    bool isAnyInstanceBuildComplete = false;
                    if (index.Instances.Count() > 1)
                    {
                        foreach (var instance in index.Instances.Keys)
                        {
                            if (instance != currentInstance.Name)
                            {
                                isAnyInstanceBuildComplete = IsInstanceAvailable(repository, indexName, instance);
                                if (isAnyInstanceBuildComplete)
                                    break;
                            }
                        }
                    }
                    else
                    {
                        //just one current instance exist
                        isAnyInstanceBuildComplete = true;
                    }
                    //build the current instance if any other instance complete or if the instance was never built
                    if (isAnyInstanceBuildComplete || GetInstanceLatestStatus(repository, indexName, currentInstance.Name) == null)
                    {
                        // Building the current instance
                        indexService.BuildIndex(repository, indexName, currentInstance.Name, buildName);
                    }
                }
            }
            else
            {
                throw new ArgumentException(string.Format("Unable to load index: '{0}' in repository: '{1}'", indexName, repository));
            }
        }

Votes for this answer: 1
 
Anders Ditlevsen
Anders Ditlevsen
Reply

Thank you Nicolai :)

 

You must be logged in to post in the forum