diff --git a/src/Discord.Net/MessageQueue.cs b/src/Discord.Net/MessageQueue.cs index ba7204ed5..40ece5a14 100644 --- a/src/Discord.Net/MessageQueue.cs +++ b/src/Discord.Net/MessageQueue.cs @@ -34,7 +34,6 @@ namespace Discord.Net private readonly ConcurrentQueue _pendingEdits; private readonly ConcurrentQueue _pendingDeletes; private readonly ConcurrentDictionary _pendingSendsByNonce; - //private readonly ConcurrentQueue _pendingTasks; private int _nextWarning; private int _count; @@ -52,7 +51,6 @@ namespace Discord.Net _pendingEdits = new ConcurrentQueue(); _pendingDeletes = new ConcurrentQueue(); _pendingSendsByNonce = new ConcurrentDictionary(); - //_pendingTasks = new ConcurrentQueue(); } internal Message QueueSend(Channel channel, string text, bool isTTS) @@ -101,8 +99,7 @@ namespace Discord.Net { RunSendQueue(cancelToken), RunEditQueue(cancelToken), - RunDeleteQueue(cancelToken), - //RunTaskQueue(cancelToken) + RunDeleteQueue(cancelToken) }; } private Task RunSendQueue(CancellationToken cancelToken) @@ -116,15 +113,32 @@ namespace Discord.Net Message msg; while (_pendingSends.TryDequeue(out msg)) { + DecrementCount(); string text; - if (_pendingSendsByNonce.TryRemove(msg.Nonce, out text)) //If it was delete from queue, this will fail + if (_pendingSendsByNonce.TryRemove(msg.Nonce, out text)) //If it was deleted from queue, this will fail { - msg.RawText = text; - msg.Text = msg.Resolve(text); - await Send(msg).ConfigureAwait(false); + try + { + msg.RawText = text; + msg.Text = msg.Resolve(text); + var request = new SendMessageRequest(msg.Channel.Id) + { + Content = msg.RawText, + Nonce = msg.Nonce.ToString(), + IsTTS = msg.IsTTS + }; + var response = await _rest.Send(request).ConfigureAwait(false); + msg.State = MessageState.Normal; + msg.Id = response.Id; + msg.Update(response); + } + catch (Exception ex) + { + msg.State = MessageState.Failed; + _logger.Error("Failed to send message", ex); + } } } - await Task.Delay((int)Discord.DiscordConfig.MessageQueueInterval).ConfigureAwait(false); } } @@ -142,11 +156,23 @@ namespace Discord.Net MessageEdit edit; while (_pendingEdits.TryPeek(out edit) && edit.Message.State != MessageState.Queued) { - _pendingEdits.TryDequeue(out edit); - if (edit.Message.State == MessageState.Normal) - await Edit(edit.Message, edit.NewText).ConfigureAwait(false); + if (_pendingEdits.TryDequeue(out edit)) + { + DecrementCount(); + if (edit.Message.State == MessageState.Normal) + { + try + { + var request = new UpdateMessageRequest(edit.Message.Channel.Id, edit.Message.Id) + { + Content = edit.NewText + }; + await _rest.Send(request).ConfigureAwait(false); + } + catch (Exception ex) { _logger.Error("Failed to edit message", ex); } + } + } } - await Task.Delay((int)Discord.DiscordConfig.MessageQueueInterval).ConfigureAwait(false); } } @@ -164,9 +190,20 @@ namespace Discord.Net Message msg; while (_pendingDeletes.TryPeek(out msg) && msg.State != MessageState.Queued) { - _pendingDeletes.TryDequeue(out msg); - if (msg.State == MessageState.Normal) - await Delete(msg).ConfigureAwait(false); + if (_pendingDeletes.TryDequeue(out msg)) + { + DecrementCount(); + if (msg.State == MessageState.Normal) + { + try + { + var request = new DeleteMessageRequest(msg.Channel.Id, msg.Id); + await _rest.Send(request).ConfigureAwait(false); + } + catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } //Ignore + catch (Exception ex) { _logger.Error("Failed to delete message", ex); } + } + } } await Task.Delay((int)Discord.DiscordConfig.MessageQueueInterval).ConfigureAwait(false); @@ -175,86 +212,6 @@ namespace Discord.Net catch (OperationCanceledException) { } })); } - /*private Task RunTaskQueue(CancellationToken cancelToken) - { - return Task.Run(async () => - { - Task task; - while (!cancelToken.IsCancellationRequested) - { - while (_pendingTasks.TryPeek(out task) && task.IsCompleted) - { - _pendingTasks.TryDequeue(out task); //Should never fail - if (task.IsFaulted) - _logger.Warning("Error during Edit/Delete", task.Exception); - } - await Task.Delay((int)Discord.DiscordConfig.MessageQueueInterval).ConfigureAwait(false); - } - - //Wait for remaining tasks to complete - while (_pendingTasks.TryDequeue(out task)) - { - if (!task.IsCompleted) - await task.ConfigureAwait(false); - } - }); - }*/ - - internal async Task Send(Message msg) - { - try - { - var request = new SendMessageRequest(msg.Channel.Id) - { - Content = msg.RawText, - Nonce = msg.Nonce.ToString(), - IsTTS = msg.IsTTS - }; - var response = await _rest.Send(request).ConfigureAwait(false); - msg.State = MessageState.Normal; - msg.Id = response.Id; - msg.Update(response); - } - catch (Exception ex) - { - msg.State = MessageState.Failed; - _logger.Error("Failed to send message", ex); - } - } - internal async Task Edit(Message msg, string text) - { - if (msg.State == MessageState.Normal) - { - try - { - var request = new UpdateMessageRequest(msg.Channel.Id, msg.Id) - { - Content = text - }; - await _rest.Send(request).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.Error("Failed to edit message", ex); - } - } - } - internal async Task Delete(Message msg) - { - if (msg.State == MessageState.Normal) - { - try - { - var request = new DeleteMessageRequest(msg.Channel.Id, msg.Id); - await _rest.Send(request).ConfigureAwait(false); - } - catch (HttpException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { } //Ignore - catch (Exception ex) - { - _logger.Error("Failed to delete message", ex); - } - } - } private void IncrementCount() { @@ -267,6 +224,12 @@ namespace Discord.Net else if (count < WarningStart) //Reset once the problem is solved _nextWarning = WarningStart; } + private void DecrementCount() + { + int count = Interlocked.Decrement(ref _count); + if (count < WarningStart) //Reset once the problem is solved + _nextWarning = WarningStart; + } /// Clears all queued message sends/edits/deletes. public void Clear() @@ -274,9 +237,12 @@ namespace Discord.Net Message msg; MessageEdit edit; - while (_pendingSends.TryDequeue(out msg)) { } - while (_pendingEdits.TryDequeue(out edit)) { } - while (_pendingDeletes.TryDequeue(out msg)) { } + while (_pendingSends.TryDequeue(out msg)) + DecrementCount(); + while (_pendingEdits.TryDequeue(out edit)) + DecrementCount(); + while (_pendingDeletes.TryDequeue(out msg)) + DecrementCount(); _pendingSendsByNonce.Clear(); }