Exemplo n.º 1
0
            public SemaphoreBulkheadHolder(GroupKey key, IMetricEvents metricEvents, MjolnirConfiguration config, IMjolnirLogFactory logFactory)
            {
                _key          = key;
                _metricEvents = metricEvents ?? throw new ArgumentNullException(nameof(metricEvents));
                _config       = config ?? throw new ArgumentNullException(nameof(config));

                if (logFactory == null)
                {
                    throw new ArgumentNullException(nameof(logFactory));
                }

                _log = logFactory.CreateLog <SemaphoreBulkheadHolder>();
                if (_log == null)
                {
                    throw new InvalidOperationException($"{nameof(IMjolnirLogFactory)} implementation returned null from {nameof(IMjolnirLogFactory.CreateLog)} for type {typeof(SemaphoreBulkheadHolder)}, please make sure the implementation returns a non-null log for all calls to {nameof(IMjolnirLogFactory.CreateLog)}");
                }

                // The order of things here is very intentional.
                // We get the MaxConcurrent value first and then initialize the semaphore bulkhead.
                // The change handler is registered after that. The order ought to help avoid a
                // situation where we might fire a config change handler before we add the
                // semaphore to the dictionary, potentially trying to add two entries with
                // different values in rapid succession.

                var value = _config.GetBulkheadConfiguration(key.Name).MaxConcurrent;

                _bulkhead = new SemaphoreBulkhead(_key, value);

                // On change, we'll replace the bulkhead. The assumption here is that a caller
                // using the bulkhead will have kept a local reference to the bulkhead that they
                // acquired a lock on, and will release the lock on that bulkhead and not one that
                // has been replaced after a config change.
                _config.OnConfigurationChanged(c => c.GetBulkheadConfiguration(key.Name).MaxConcurrent, UpdateMaxConcurrent);
            }
Exemplo n.º 2
0
            internal void UpdateMaxConcurrent(int newLimit)
            {
                if (!IsValidMaxConcurrent(newLimit))
                {
                    _log.Error($"Semaphore bulkhead config for key {_key} changed to an invalid limit of {newLimit}, the bulkhead will not be changed");
                    return;
                }

                _bulkhead = new SemaphoreBulkhead(_key, newLimit);
            }