HostManager.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using System.Collections.Generic;
  2. using Best.HTTP.Hosts.Connections;
  3. using Best.HTTP.Shared;
  4. namespace Best.HTTP.HostSetting
  5. {
  6. /*
  7. ┌───────────────┐
  8. ┌──────┤ HostManager ├──────────────────────┐
  9. │ └───────────────┘ │
  10. │ │
  11. ┌──────────▼───────┐ ┌──────────▼────────┐
  12. │ HostVariant │ │ HostVariant │
  13. │(http://host:port)│ │(https://host:port)│
  14. ┌────┴──────┬──────────┬┘ ┌────┴──────┬───────────┬┘
  15. │ │ │ │ │ │
  16. ┌──────▼──────┐ ┌──▼──┐ ▼ ┌──────▼──────┐ ┌──▼──┐ ▼
  17. │ Connections │ │Queue│ ProtocolSupport │ Connections │ │Queue│ ProtocolSupport
  18. ├─────────────┤ ├─────┤ (http/1.1) ├─────────────┤ ├─────┤ (http/1.1, h2)
  19. │ ... │ │ ... │ │ ... │ │ ... │
  20. │ ... │ │ ... │ │ ... │ │ ... │
  21. │ ... │ │ ... │ │ ... │ │ ... │
  22. │ ... │ │ ... │ │ ... │ │ ... │
  23. └─────────────┘ └─────┘ └─────────────┘ └─────┘
  24. */
  25. /// <summary>
  26. /// The <see cref="HostManager"/> class provides centralized management for <see cref="HostVariant"/> objects associated with HTTP requests and connections.
  27. /// </summary>
  28. /// <remarks>
  29. /// <para>
  30. /// The <see cref="HostManager"/> class acts as a central registry for managing <see cref="HostVariant"/> objects, each associated with a unique <see cref="HostKey"/>.
  31. /// It facilitates the creation, retrieval, and management of <see cref="HostVariant"/> instances based on HTTP requests and connections.
  32. /// </para>
  33. /// <para>
  34. /// A <see cref="HostVariant"/> represents a specific host and port combination (e.g., "http://example.com:80" or "https://example.com:443") and
  35. /// manages the connections and request queues for that host. The class ensures that a single <see cref="HostVariant"/> instance is used for
  36. /// each unique host, helping optimize resource usage and connection pooling.
  37. /// </para>
  38. /// <para>
  39. /// Key features of the <see cref="HostManager"/> class include:
  40. /// </para>
  41. /// <list type="bullet">
  42. /// <item>
  43. /// <term>Creation and Retrieval</term>
  44. /// <description>
  45. /// The class allows you to create and retrieve <see cref="HostVariant"/> instances based on HTTP requests, connections, or <see cref="HostKey"/>.
  46. /// It ensures that a single <see cref="HostVariant"/> is used for each unique host.
  47. /// </description>
  48. /// </item>
  49. /// <item>
  50. /// <term>Queue Management</term>
  51. /// <description>
  52. /// The <see cref="HostManager"/> manages the queue of pending requests for each <see cref="HostVariant"/>, ensuring efficient request processing.
  53. /// </description>
  54. /// </item>
  55. /// <item>
  56. /// <term>Connection Management</term>
  57. /// <description>
  58. /// The class handles the management of connections associated with <see cref="HostVariant"/> objects, including recycling idle connections,
  59. /// removing idle connections, and shutting down connections when needed.
  60. /// </description>
  61. /// </item>
  62. /// </list>
  63. /// <para>
  64. /// Usage of the <see cref="HostManager"/> class is typically transparent to developers and is handled internally by the Best HTTP library. However,
  65. /// it provides a convenient and efficient way to manage connections and requests when needed.
  66. /// </para>
  67. /// </remarks>
  68. public static class HostManager
  69. {
  70. /// <summary>
  71. /// Dictionary to store <see cref="HostKey"/>-<see cref="HostVariant"/> mappings.
  72. /// </summary>
  73. private static Dictionary<HostKey, HostVariant> hosts = new Dictionary<HostKey, HostVariant>();
  74. /// <summary>
  75. /// Gets the <see cref="HostVariant"/> associated with an HTTP request.
  76. /// </summary>
  77. /// <param name="request">The HTTP request.</param>
  78. /// <returns>The <see cref="HostVariant"/> for the request's host.</returns>
  79. public static HostVariant GetHostVariant(HTTPRequest request) => GetHostVariant(request.CurrentHostKey);
  80. /// <summary>
  81. /// Gets the <see cref="HostVariant"/> associated with a connection.
  82. /// </summary>
  83. /// <param name="connection">The HTTP connection.</param>
  84. /// <returns>The <see cref="HostVariant"/> for the connection's host.</returns>
  85. public static HostVariant GetHostVariant(ConnectionBase connection) => GetHostVariant(connection.HostKey);
  86. /// <summary>
  87. /// Gets the <see cref="HostVariant"/> associated with a HostKey.
  88. /// </summary>
  89. /// <param name="key">The HostKey for which to get the HostVariant.</param>
  90. /// <returns>The <see cref="HostVariant"/> for the specified HostKey.</returns>
  91. public static HostVariant GetHostVariant(HostKey key)
  92. {
  93. if (!hosts.TryGetValue(key, out var variant))
  94. {
  95. var settings = HTTPManager.PerHostSettings.Get(key).HostVariantSettings;
  96. variant = settings?.VariantFactory?.Invoke(settings, key) ?? new HostVariant(key);
  97. hosts.Add(key, variant);
  98. HTTPManager.Logger.Information("HostManager", $"Variant added with key: {key}");
  99. }
  100. return variant;
  101. }
  102. /// <summary>
  103. /// Removes all idle connections for all hosts.
  104. /// </summary>
  105. public static void RemoveAllIdleConnections()
  106. {
  107. HTTPManager.Logger.Information("HostManager", "RemoveAllIdleConnections");
  108. foreach (var host in hosts)
  109. host.Value.RemoveAllIdleConnections();
  110. }
  111. /// <summary>
  112. /// Tries to send queued requests for all hosts.
  113. /// </summary>
  114. public static void TryToSendQueuedRequests()
  115. {
  116. foreach (var kvp in hosts)
  117. kvp.Value.TryToSendQueuedRequests();
  118. }
  119. /// <summary>
  120. /// Shuts down all connections for all hosts.
  121. /// </summary>
  122. public static void Shutdown()
  123. {
  124. HTTPManager.Logger.Information("HostManager", "Shutdown()");
  125. foreach (var kvp in hosts)
  126. kvp.Value.Shutdown();
  127. }
  128. /// <summary>
  129. /// Clears all hosts and their associated variants.
  130. /// </summary>
  131. public static void Clear()
  132. {
  133. HTTPManager.Logger.Information("HostManager", "Clearing()");
  134. hosts.Clear();
  135. }
  136. }
  137. }