Example #1
0
        internal void UnlockSocket(SocketLockToken token) // TODO : доделать
        {
            switch (token.type)
            {
            case LockType.Receive:
                if (Interlocked.Decrement(ref receivingLockersCount) == 0)
                {
                    socketReceiveLocked = false;
                    if (receiveKernelWaitingsCount != 0)
                    {
                        receiveARE.Set();
                    }
                }
                break;

            case LockType.Send:
                SocketSendLockToken sendToken = token as SocketSendLockToken;
                if (sendToken.IsHardLocked)
                {
                    if (Interlocked.Decrement(ref sendingHardLockersCount) == 0)
                    {
                        socketSendHardLocked = false;
                    }
                }
                if (Interlocked.Decrement(ref sendingLockersCount) == 0)
                {
                    socketSendSoftLocked = false;
                    if (sendKernelWaitingsCount != 0)
                    {
                        sendARE.Set();
                    }
                }
                break;

            case LockType.Suspend:
                if (Interlocked.Decrement(ref receivingLockersCount) == 0)
                {
                    socketReceiveLocked = false;
                    if (receiveKernelWaitingsCount != 0)
                    {
                        receiveARE.Set();
                    }
                }
                if (Interlocked.Decrement(ref sendingHardLockersCount) == 0)
                {
                    socketSendHardLocked = false;
                }
                if (Interlocked.Decrement(ref sendingLockersCount) == 0)
                {
                    socketSendSoftLocked = false;
                    if (sendKernelWaitingsCount != 0)
                    {
                        sendARE.Set();
                    }
                }
                break;
            }
        }
Example #2
0
        private async void ListenToRateLimit()
        {
            int       oneMinute = 60000; //From ms
            int       limit     = 120;
            Stopwatch stopwatch = new Stopwatch();

            while (true)
            {
                stopwatch.Start();
                while (stopwatch.ElapsedMilliseconds < oneMinute)
                {
                    // Здесь может возникнуть вопрос "А почему мы используем ограничение равное 118?"
                    // Ответом на этот вопрос будет то, что ограничение отправляемых к Gateway дискорда
                    // Равняется 120 запросов\минута. Но некоторые запросы, такие как Hearbeat
                    // Необходимо отправлять каждые, в данный момент времени, 41.5 секунд.
                    // Для решения это проблемы я ввёл ограничение на (limit - 2) запроса, дабы
                    // 2 запроса остались в запасе для приоритетных запросов.
                    if (payloadSentLastMinute == limit - 2) //TODO : вынести хардлок в конфиг?
                    {
                        using (SocketSendLockToken token = socketHelper.GetSendingLock())
                        {
                            while (stopwatch.ElapsedMilliseconds < oneMinute)
                            {
                                if (payloadSentLastMinute == limit)
                                {
                                    token.HardLockSocket();
                                    TimeSpan msToWait = TimeSpan.FromMilliseconds(oneMinute - stopwatch.ElapsedMilliseconds); //Через этот отрезок времени наступит новая минута => можно сбрасывать счётчик;
                                    ReachedRateLimit(msToWait);
                                    await Task.Delay(msToWait);

                                    break;
                                }
                            }
                        }
                    }
                    //TODO : здесь всё же может быть проблема с тем, что количество пакетов будет == 120, даже с HighPriority
                }
                Interlocked.Exchange(ref payloadSentLastMinute, 0);
                stopwatch.Restart();
            }
        }