// Used for private chats, groups, supergroups and channels when they are referenced by ID private void WaitOneInternalLocked(long chatId) { ManualResetEvent mre = null; if (chatId > 0) { lock (QueueLock) { if (RequestCounts.TryGetValue(chatId, out ChatRequestCount ChatRequestCount)) { if (ChatRequestCount.GetRequestCount(PrivateChatIntervals) <= PrivateChatMaxBurst) { ChatRequestCount.Increment(); mre = WaitOneInternalUnlocked(); } else { var requestItem = new ScheduledRequestItem(TimerIntervals, chatId); PrivateChatQueue.AddLast(requestItem); mre = requestItem.MRE; } } else { RequestCounts.Add(chatId, new ChatRequestCount(1, PrivateChatIntervals)); mre = WaitOneInternalUnlocked(); } } } else { lock (QueueLock) { if (RequestCounts.TryGetValue(chatId, out ChatRequestCount ChatRequestCount)) { if (ChatRequestCount.GetRequestCount(GroupChatIntervals) <= GroupChatMaxBurst) { ChatRequestCount.Increment(); mre = WaitOneInternalUnlocked(); } else { var requestItem = new ScheduledRequestItem(TimerIntervals, chatId); GroupChatQueue.AddLast(requestItem); mre = requestItem.MRE; } } else { RequestCounts.Add(chatId, new ChatRequestCount(1, GroupChatIntervals)); mre = WaitOneInternalUnlocked(); } } } mre?.WaitOne(); return; }
private void TimerCallback(object state) { TimerIntervals++; long msElapsed = Stopwatch.ElapsedMilliseconds; bool CanUpdatePrivateChats = msElapsed > (PrivateChatIntervals + 1) * SafePrivateChatInterval; if (CanUpdatePrivateChats) { PrivateChatIntervals++; } bool CanUpdateGroupChats = msElapsed > (GroupChatIntervals + 1) * SafeGroupChatInterval; if (CanUpdateGroupChats) { GroupChatIntervals++; } lock (QueueLock) { if (CanUpdatePrivateChats && PrivateChatQueue.Count != 0) { LinkedListNode <ScheduledRequestItem> lastAddedNode = null; var node = PrivateChatQueue.First; do { ChatRequestCount requestCount = RequestCounts[node.Value.ChatId]; if (requestCount.GetRequestCount(PrivateChatIntervals) <= PrivateChatMaxBurst) { requestCount.Increment(); lastAddedNode = InsertToGeneralQueue(node.Value, lastAddedNode); } node = node.Next; }while (node != null); } if (CanUpdateGroupChats && GroupChatQueue.Count != 0) { LinkedListNode <ScheduledRequestItem> lastAddedNode = null; var node = GroupChatQueue.First; do { ChatRequestCount requestCount = RequestCounts[node.Value.ChatId]; if (requestCount.GetRequestCount(GroupChatIntervals) <= GroupChatMaxBurst) { requestCount.Increment(); lastAddedNode = InsertToGeneralQueue(node.Value, lastAddedNode); } node = node.Next; }while (node != null); } if (GeneralRequestCount <= GeneralMaxBurst && GeneralQueue.Count != 0) { GeneralQueue.First.Value.MRE.Set(); GeneralQueue.RemoveFirst(); } else if (GeneralRequestCount > 0) { GeneralRequestCount--; } } int wait = Math.Max(SafeGeneralInterval / 2, (int)((TimerIntervals + 1) * SafeGeneralInterval - msElapsed)); Timer.Change(wait, Timeout.Infinite); }