Hi,
We noticed that the new index always uses the first instance, instead of getting the most recently built. Shouldn't it pull from the most recently built?
http://screencast.com/t/lQ13hVmt
Best Regards,
Nuno Aguiar
Hi,
We noticed that the new index always uses the first instance, instead of getting the most recently built. Shouldn't it pull from the most recently built?
http://screencast.com/t/lQ13hVmt
Best Regards,
Nuno Aguiar
Hi Nuno
That is not how it is designed. You instance B will be used if A is unavailable - if it fails or if it is being updated.
Hi Nicolai,
I see and makes some sense, but at the same time, if you don't get the most recent index, there's no point in allowing more than 2 instances.
I was hoping we could create dummy instances with new fields to test whatever we needed, and don't touch instance A and/or B. In the end we could rebuild instances A and/or B and delete our test (C) instance.
I guess you can do the same thing if you create instance C and leave that as a backup, but sounds like a very simple change to get the most recent instance instead of the first one. Do you see any issues with it?
Best Regards,
Nuno Aguiar
The idea is that you index all instances in a row. The reason you have more than one, is that they are unavailable when being indexed and if they somehow fail. If a build fails, the indexing stops and the solution keeps running on instance 2.
If you want to test, create a new index.
The concept of having more instances and choosing one of them is called Balancing in DW. How the balancing works is provider based on DW currently only have ActivePassive balancer that behaves like this. You can create your own balancer if you feel like having another behavior.
The ActivePasive balancer in DW:
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace Dynamicweb.Indexing.Balancing
{
/// <summary>
/// Represents ActivePassive index balancer class
/// </summary>
public class ActivePassive : IIndexBalancer
{
private static readonly object lockObject = new object();
private string ActiveInstance
{
get
{
lock (lockObject)
{
try
{
var balancer = GetBalancerFileName();
return File.Exists(balancer) ? File.ReadAllText(balancer, Encoding.UTF8) : string.Empty;
}
catch
{
return string.Empty;
}
}
}
set
{
lock (lockObject)
{
try
{
var balancer = GetBalancerFileName();
File.WriteAllText(balancer, value, Encoding.UTF8);
}
catch
{ }
}
}
}
/// <summary>
/// Gets or sets index
/// </summary>
[JsonIgnore]
[XmlIgnore]
public IIndex Index { get; set; }
/// <summary>
/// Gets index provider instance
/// </summary>
/// <returns></returns>
public IIndexProvider GetInstance()
{
var activeInstance = ActiveInstance;
var candidate = !string.IsNullOrEmpty(activeInstance) && Index.Instances.ContainsKey(activeInstance)
? Index.Instances[activeInstance]
: null;
if (candidate == null || !candidate.IsAvailable)
candidate = Index.Instances.Values.FirstOrDefault(i => i.IsAvailable);
return candidate;
}
/// <summary>
/// Sets active instance
/// </summary>
/// <param name="name"></param>
public void SetInstance(string name)
{
ActiveInstance = name;
}
private string GetBalancerFileName()
{
return Path.Combine(IndexLocationResolver.ResolveLocation(Index), this.GetType().Name);
}
}
}
Hi Nicolai,
Gotcha. I was hoping we would get the EndTime of a given instance and could do something like this.
if (candidate == null || !candidate.IsAvailable) candidate = Index.Instances.Values.OrderBy(i => i.EndTime).FirstOrDefault(i => i.IsAvailable);
Is there a way to get that time stamp and do this? Or would you be able to make that available on the Instances object?
Best Regards,
Nuno Aguiar
An instance is basically a folder on disk, so you can have a look at some last write timestamps on that folder.
BR Nicolai
Hi Nicolai,
Thank you. We made the change for the required project and worked likea charm. Here's the code in case you would consider updating the core funcionality.
We left the original code commented.
public IIndexProvider GetInstance()
{
/*
var activeInstance = ActiveInstance;
var candidate = !string.IsNullOrEmpty(activeInstance) && Index.Instances.ContainsKey(activeInstance)
? Index.Instances[activeInstance]
: null;
if (candidate == null || !candidate.IsAvailable)
candidate = Index.Instances.Values.FirstOrDefault(i => i.IsAvailable);
return candidate;
*/
// based folder of indexes
var basedFolder = IndexLocationResolver.ResolveLocation(Index);
// collection to find the most recent index
Dictionary<string, System.DateTime> dic = new Dictionary<string, System.DateTime>();
foreach (var instanceName in Index.Instances.Values.Where(i => i.IsAvailable).Select(i => i.Name))
{
// get datetime of build
var buildDir = new DirectoryInfo(Path.Combine(basedFolder, instanceName));
dic.Add(instanceName, buildDir.LastWriteTime);
}
// get the correct instance name
ActiveInstance = dic.OrderByDescending(d => d.Value).First().Key;
return Index.Instances[ActiveInstance];
}
Best Regards,
Nuno Aguiar
You must be logged in to post in the forum