1
wtt
2024-08-16 e03677790c63aba9379b84c976d172c3dcd0127a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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);
            }
        }
    }
}