Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using NLog;
- namespace Common
- {
- /// <summary>
- /// Provides server hosts for the search service
- /// </summary>
- public class SearchHostManager
- {
- static readonly Logger _logger = LogManager.GetCurrentClassLogger();
- readonly object syncRoot = new object();
- readonly string[] _allhosts;
- readonly List<string> _availableHosts;
- readonly int _secondsToReset;
- readonly int _searchTimeOut;
- DateTime _lastHostReset = DateTime.Now;
- public SearchHostManager(string[] hosts, int timeout = 5000, int resetInSeconds = 60)
- {
- _allhosts = hosts.ToArray();
- _availableHosts = new List<string>(_allhosts);
- _searchTimeOut = timeout;
- _secondsToReset = resetInSeconds;
- }
- /// <summary>
- /// Gets all hosts regardless if they are valid or not
- /// </summary>
- public string[] AllHosts
- {
- get { return _allhosts.ToArray(); }
- }
- /// <summary>
- /// Gets the number of seconds to reset failed hosts back to the original hosts. The default value is 60 seconds (1 minute).
- /// </summary>
- public int SecondsToReset
- {
- get { return _secondsToReset; }
- }
- /// <summary>
- /// Gets the number of milliseconds to wait before the request times out. The default value is 5000 milliseconds (5 seconds).
- /// </summary>
- public int SearchTimeOut
- {
- get { return _searchTimeOut; }
- }
- /// <summary>
- /// Gets the number of maximum attempts that can be made with the hosts
- /// </summary>
- public int MaxSearchAttempts
- {
- get { return _allhosts.Length; }
- }
- /// <summary>
- /// Returns an array of available hosts that are valid
- /// </summary>
- public string[] GetAvailableHosts()
- {
- lock (syncRoot)
- {
- if (DateTime.Now.Subtract(_lastHostReset) > TimeSpan.FromSeconds(_secondsToReset))
- {
- _lastHostReset = DateTime.Now;
- _availableHosts.Clear();
- _availableHosts.AddRange(_allhosts);
- _logger.Debug("Search hosts reset");
- }
- var hosts = _availableHosts.ToArray();
- if (hosts.Length == 0)
- {
- _availableHosts.AddRange(_allhosts);
- hosts = _availableHosts.ToArray();
- }
- return hosts;
- }
- }
- /// <summary>
- /// Removes a failed host from the available hosts
- /// </summary>
- public void RemoveHost(string host)
- {
- lock (syncRoot)
- _availableHosts.Remove(host);
- }
- /// <summary>
- /// Returns a random host from the available hosts
- /// </summary>
- public string GetNextHost(string currentHost = null)
- {
- var hosts = GetAvailableHosts().ToList();
- if(!string.IsNullOrWhiteSpace(currentHost))
- hosts.Remove(currentHost);
- return GetNextHost(hosts.ToArray());
- }
- /// <summary>
- /// Returns a random host from the available hosts
- /// </summary>
- public string GetNextHost(string[] hosts)
- {
- if (hosts.Length == 0)
- return null;
- Random rnd = new Random(Math.Abs(Guid.NewGuid().ToString().GetHashCode()));
- string h = hosts[rnd.Next(0, hosts.Length)];
- return h;
- }
- /// <summary>
- /// Replaces the host and port (if non-standard) in the provided url
- /// </summary>
- public string ReplaceHostInUrl(string url, string host)
- {
- string h = host;
- int port = url.StartsWith("https") ? 443 : 80;
- if (host.IndexOf(":") > 0)
- {
- var parts = host.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
- if (parts.Length == 2)
- {
- h = parts[0];
- int.TryParse(parts[1], out port);
- }
- }
- UriBuilder ubuilder = new UriBuilder(url);
- ubuilder.Host = h;
- if (port > 0)
- ubuilder.Port = port;
- return ubuilder.Uri.ToString();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment