Example #1
0
 async Task SendPriorityAsync(HubMethodCall msg)
 {
     if (RequireSendConfirmation)
     {
         await conn.InvokeCoreAsync(msg.MethodName, msg.Args);
     }
     else
     {
         priority.Enqueue(msg);
         flushes.Add(Flush());
     }
 }
Example #2
0
            async Task Flush()
            {
                try
                {
                    await flushing.WaitAsync();

                    if (flushCancellation.IsCancellationRequested)
                    {
                        return;
                    }

                    HubMethodCall priorityMethod = null, standardMethod = null;

                    while (priority.TryPeek(out priorityMethod) || standard.TryPeek(out standardMethod))
                    {
                        while (conn.State != HubConnectionState.Connected && !flushCancellation.IsCancellationRequested)
                        {
                            await Task.Delay(MinDelay);
                        }

                        if (flushCancellation.IsCancellationRequested)
                        {
                            break;
                        }

                        bool dequeued   = false;
                        bool isPriority = priorityMethod != null;
                        var  method     = priorityMethod ?? standardMethod;

                        try
                        {
                            method.Attempts++;
                            if (!RequireSendConfirmation && (method.MethodName == nameof(ItemResult) || method.MethodName == nameof(Log)))
                            {
                                await conn.SendCoreAsync(method.MethodName, method.Args);
                            }
                            else
                            {
                                await conn.InvokeCoreAsync(method.MethodName, method.Args);
                            }

                            dequeued = isPriority ? priority.TryDequeue(out _) : standard.TryDequeue(out _);
                        }
                        catch (Exception ex)
                        {
                            if (method.Attempts > 3)
                            {
                                logger.LogError(ex, $"Message discarded after 3 attempts: {method.MethodName}");

                                if (!dequeued)
                                {
                                    _ = isPriority ? priority.TryDequeue(out _) : standard.TryDequeue(out _);
                                }
                            }
                            else
                            {
                                int retryDelay = new Random().Next(0, 5) * MinDelay;
                                logger.LogWarning(ex, "Could not send {method} message to server. Will retry in {retryDelay}ms.", method.MethodName, retryDelay);
                                await Task.Delay(retryDelay);
                            }
                        }

                        priorityMethod = null;
                        standardMethod = null;
                    }
                }
                finally
                {
                    flushing.Release();
                }
            }