public int UpdateNextRebootTime(EasyIpAcl acl, DateTime nextRebootTime) { int count = 0; var gateIdList = this.GateTable.Where(x => acl.Evaluate(x.Value.IpAddress) == EasyIpAclAction.Permit).Select(x => x.Key).ToArray(); ImmutableInterlocked.Update(ref this.GateTable, table => { foreach (var id in gateIdList) { if (table.TryGetValue(id, out ThinGate? gate)) { gate.NextRebootTime = nextRebootTime; count++; } } return(table); }); return(count); }
public ThinGate?SelectBestGateForServer(EasyIpAcl preferAcl, int gateMaxSessions, bool allowCandidate2, string preferGate) { DateTime now = DtNow; var table = this.GateTable; // 現在アクティブな Gate で有効期限が切れていないもののリスト var candidates2 = table.Values.Where(x => now <= x.Expires); if (preferGate._IsFilled()) { // 特定の Gate を特に希望 var gg = candidates2.Where(x => x.IpAddress._IsSamei(preferGate) && x.NumSessions < (gateMaxSessions * 2)).FirstOrDefault(); if (gg != null) { return(gg); } } // これらの Gate の中でセッション数が MaxSessionsPerGate 以下のもののリスト if (gateMaxSessions != 0) { candidates2 = candidates2.Where(x => x.NumSessions < gateMaxSessions); } // これらの Gate の中で希望 IP アドレスリストの範囲内であるものを candidates1 とする // 希望 IP アドレスの範囲にかかわらずすべての適合 Gate を candidates2 とする var candidates1 = candidates2.Where(x => preferAcl.Evaluate(x.IpAddress) == EasyIpAclAction.Permit); List <IEnumerable <ThinGate> > candidatesList = new List <IEnumerable <ThinGate> >(); candidatesList.Add(candidates1); if (allowCandidate2) { candidatesList.Add(candidates2); } // 1/2 の確率で、「force_random_mode」を有効にする。 // 「force_random_mode」の場合は、最小セッション数は無関係にすべての適応ホストから無作為に 1 つ選択する。 bool force_random_mode = Util.RandBool(); foreach (var candidates in candidatesList) { IEnumerable <ThinGate> selectedGates; if (force_random_mode == false) { // 候補を load をもとにソートする List <Pair2 <ThinGate, double> > sortList = new List <Pair2 <ThinGate, double> >(); foreach (var gate in candidates) { double load = gate.CalcLoad(); sortList.Add(new Pair2 <ThinGate, double>(gate, load)); } // 最も低い load の値を取得 double minLoad = sortList.OrderBy(x => x.B).Select(x => x.B).FirstOrDefault(); var minLoadCandidates = sortList.Where(x => x.B == minLoad); selectedGates = minLoadCandidates.Select(x => x.A); } else { selectedGates = candidates; } var selectedGate = selectedGates._Shuffle().FirstOrDefault(); if (selectedGate != null) { // 1 つ選定完了! return(selectedGate); } } // 全部失敗 return(null); }