using System; using System.Collections.Concurrent; using System.Collections.Generic; using BestHTTP.Logger; // Required for ConcurrentQueue.Clear extension. using BestHTTP.Extensions; namespace BestHTTP.Core { public #if CSHARP_7_OR_LATER readonly #endif struct ProtocolEventInfo { public readonly IProtocol Source; public ProtocolEventInfo(IProtocol source) { this.Source = source; } public override string ToString() { return string.Format("[ProtocolEventInfo Source: {0}]", Source); } } public static class ProtocolEventHelper { private static ConcurrentQueue protocolEvents = new ConcurrentQueue(); private static List ActiveProtocols = new List(2); #pragma warning disable 0649 public static Action OnEvent; #pragma warning restore public static void EnqueueProtocolEvent(ProtocolEventInfo @event) { if (HTTPManager.Logger.Level == Loglevels.All) HTTPManager.Logger.Information("ProtocolEventHelper", "Enqueue protocol event: " + @event.ToString(), @event.Source.LoggingContext); protocolEvents.Enqueue(@event); } internal static void Clear() { protocolEvents.Clear(); } internal static void ProcessQueue() { ProtocolEventInfo protocolEvent; while (protocolEvents.TryDequeue(out protocolEvent)) { if (HTTPManager.Logger.Level == Loglevels.All) HTTPManager.Logger.Information("ProtocolEventHelper", "Processing protocol event: " + protocolEvent.ToString(), protocolEvent.Source.LoggingContext); if (OnEvent != null) { try { OnEvent(protocolEvent); } catch (Exception ex) { HTTPManager.Logger.Exception("ProtocolEventHelper", "ProcessQueue", ex, protocolEvent.Source.LoggingContext); } } IProtocol protocol = protocolEvent.Source; protocol.HandleEvents(); if (protocol.IsClosed) { ActiveProtocols.Remove(protocol); HostManager.GetHost(protocol.ConnectionKey.Host) .GetHostDefinition(protocol.ConnectionKey.Connection) .TryToSendQueuedRequests(); protocol.Dispose(); } } } internal static void AddProtocol(IProtocol protocol) { ActiveProtocols.Add(protocol); } internal static void CancelActiveProtocols() { for (int i = 0; i < ActiveProtocols.Count; ++i) { var protocol = ActiveProtocols[i]; protocol.CancellationRequested(); } } } }