/// <summary> /// Performs the configuration of cache hosts configured in the application configuration file. /// </summary> /// <param name="configuration">Configuration data.</param> /// <param name="currentCacheHostBucket">Current cache host list.</param> private void PerformCacheHostsFromConfiguration(CacheClientConfigurationSection configuration, CacheHostBucket currentCacheHostBucket) { // Get the host redundancy layers from configuration var hostRedundancyLayers = configuration.HostRedundancyLayers; // Get the cache hosts from configuration var cacheHosts = configuration.CacheHosts; // Sanitize if (cacheHosts == null) { _logger.Info("No hosts configured", "No cache hosts configured in config file"); return; } // Assign the cache hosts to buckets in a specified order foreach (CacheHostElement cacheHost in cacheHosts.OfType <CacheHostElement>().OrderBy(i => i.Address).ThenBy(i => i.Port)) { // Instantiate a communication client var communicationClient = new CommunicationClient(cacheHost.Address, cacheHost.Port, configuration.HostReconnectIntervalSeconds * 1000, configuration.MessageBufferSize, configuration.CommunicationTimeoutSeconds * 1000, configuration.MaximumMessageSizeKB * 1024); // Hook up the disconnected and reconnected events communicationClient.Disconnected += OnClientDisconnected; communicationClient.Reconnected += OnClientReconnected; // Hook up the message receive event communicationClient.MessageReceived += ReceiveMessage; // Add to cache host bucket currentCacheHostBucket.AddCacheHost(communicationClient); // check if done with bucket if (currentCacheHostBucket.Count == hostRedundancyLayers + 1) { _cacheHostBuckets.Add(currentCacheHostBucket); currentCacheHostBucket = new CacheHostBucket(); } } // Final safety check for uneven cache host distributions if (currentCacheHostBucket.Count > 0) { _cacheHostBuckets.Add(currentCacheHostBucket); } _logger.Info("Cache Host Assignment", string.Format("Assigned {0} cache hosts to {1} cache host buckets ({2} per bucket)", cacheHosts.Count, _cacheHostBuckets.Count, hostRedundancyLayers + 1)); // Now attempt to connect to each host foreach (var cacheHostBucket in _cacheHostBuckets) { cacheHostBucket.PerformActionOnAll(c => c.Connect()); } }
/// <summary> /// Brings the specified cache host online. /// </summary> /// <param name="cacheHost">The cache host.</param> /// <returns>true if successful.</returns> public bool BringOnline(CommunicationClient cacheHost) { _lock.EnterWriteLock(); try { var result = _offlineCacheHosts.Remove(cacheHost); if (result) { _cacheHosts.Add(cacheHost); } return(result); } finally { _lock.ExitWriteLock(); } }
/// <summary> /// Adds a cache host to this bucket. /// </summary> /// <param name="cacheHost">The cache host.</param> public void AddCacheHost(CommunicationClient cacheHost) { // Sanitize if (cacheHost == null) { throw new ArgumentNullException("cacheHost"); } _lock.EnterWriteLock(); try { _cacheHosts.Add(cacheHost); _cacheHostCount++; } finally { _lock.ExitWriteLock(); } }
/// <summary> /// Takes the specified cache host offline. /// </summary> /// <param name="cacheHost">The cache host.</param> /// <returns>true if successful.</returns> public bool TakeOffline(CommunicationClient cacheHost) { _lock.EnterWriteLock(); try { var result = _cacheHosts.Remove(cacheHost); if (result) { _offlineCacheHosts.Add(cacheHost); // Reset the current host to be safe _currentCacheHostIndex = 0; } return(result); } finally { _lock.ExitWriteLock(); } }
/// <summary> /// The constructor. /// </summary> public CacheClient() { // Load custom logging _logger = CustomTypesLoader.LoadLogger(); // Configure custom serializer _binarySerializer = CustomTypesLoader.LoadSerializer(); // Get the cache hosts from configuration var cacheHosts = CacheClientConfigurationSection.Settings.CacheHosts; // Get the cache host reconnect interval from configuration var hostReconnectIntervalSeconds = CacheClientConfigurationSection.Settings.HostReconnectIntervalSeconds; // Sanitize if (cacheHosts == null) { throw new ConfigurationErrorsException("At least one cache host must be specified in your application's configuration."); } // Get the host redundancy layers from configuration var hostRedundancyLayers = CacheClientConfigurationSection.Settings.HostRedundancyLayers; CacheHostBucket currentCacheHostBucket = new CacheHostBucket(); // Assign the cache hosts to buckets in a specified order foreach (CacheHostElement cacheHost in cacheHosts.OfType <CacheHostElement>().OrderBy(i => i.Address).ThenBy(i => i.Port)) { // Instantiate a communication client var communicationClient = new CommunicationClient(cacheHost.Address, cacheHost.Port, hostReconnectIntervalSeconds * 1000, 1000, 4096); // Hook up the disconnected and reconnected events communicationClient.Disconnected += OnClientDisconnected; communicationClient.Reconnected += OnClientReconnected; // Hook up the message receive event communicationClient.MessageReceived += ReceiveMessage; // Add to cache host bucket currentCacheHostBucket.AddCacheHost(communicationClient); // check if done with bucket if (currentCacheHostBucket.Count == hostRedundancyLayers + 1) { _cacheHostBuckets.Add(currentCacheHostBucket); currentCacheHostBucket = new CacheHostBucket(); } } // Final safety check for uneven cache host distributions if (currentCacheHostBucket.Count > 0) { _cacheHostBuckets.Add(currentCacheHostBucket); } _logger.Info("Cache Host Assignment", string.Format("Assigned {0} cache hosts to {1} cache host buckets ({2} per bucket)", cacheHosts.Count, _cacheHostBuckets.Count, hostRedundancyLayers + 1)); // Now attempt to connect to each host foreach (var cacheHostBucket in _cacheHostBuckets) { cacheHostBucket.PerformActionOnAll(c => c.Connect()); } }