using System;
|
using System.Collections.Generic;
|
using System.Text;
|
using System.Threading;
|
|
namespace Top.Api.Cluster
|
{
|
public sealed class ClusterManager
|
{
|
private static readonly Random random = new Random();
|
private static readonly Object initLock = new Object();
|
private static volatile DnsConfig dnsConfig = null;
|
private static volatile Thread refreshThread = null;
|
|
public static T GetElementByWeight<T>(List<T> list) where T : Weightable
|
{
|
T selected = null;
|
double totalWeight = 0d;
|
foreach (T element in list)
|
{
|
double r = random.NextDouble() * (element.Weight + totalWeight);
|
if (r >= totalWeight)
|
{
|
selected = element;
|
}
|
totalWeight += element.Weight;
|
}
|
return selected;
|
}
|
|
public static DnsConfig GetDnsConfigFromCache()
|
{
|
return dnsConfig;
|
}
|
|
public static void InitRefreshThread(ITopClient client)
|
{
|
if (refreshThread == null)
|
{
|
lock (initLock)
|
{
|
if (refreshThread == null)
|
{
|
try
|
{
|
DnsConfig remoteConfig = GetDnsConfigFromTop(client);
|
if (dnsConfig == null)
|
{
|
dnsConfig = remoteConfig;
|
}
|
else if (remoteConfig != null && remoteConfig.GetVersion() > dnsConfig.GetVersion())
|
{
|
dnsConfig = remoteConfig;
|
}
|
}
|
catch (TopException e)
|
{
|
if ("22".Equals(e.ErrorCode))
|
{
|
return; // 如果HTTP DNS服务不存在,则退出守护线程
|
}
|
}
|
|
refreshThread = new Thread(o =>
|
{
|
while (true)
|
{
|
try
|
{
|
Thread.Sleep(dnsConfig.GetRefreshInterval() * 60 * 1000);
|
dnsConfig = GetDnsConfigFromTop(client);
|
}
|
catch (Exception e)
|
{
|
Console.WriteLine(e.StackTrace);
|
Thread.Sleep(3 * 1000); // 出错则过3秒重试
|
}
|
}
|
});
|
refreshThread.IsBackground = true;
|
refreshThread.Name = "HTTP_DNS_REFRESH_THREAD";
|
refreshThread.Start();
|
}
|
}
|
}
|
}
|
|
private static DnsConfig GetDnsConfigFromTop(ITopClient client)
|
{
|
HttpdnsGetRequest req = new HttpdnsGetRequest();
|
HttpdnsGetResponse rsp = client.Execute(req);
|
if (!rsp.IsError)
|
{
|
return DnsConfig.parse(rsp.Result);
|
}
|
else
|
{
|
throw new TopException(rsp.ErrCode, rsp.ErrMsg);
|
}
|
}
|
}
|
}
|