예제 #1
0
    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);
    }
예제 #2
0
    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);
    }