Esempio n. 1
0
        private OrleansTaskScheduler(int maxActiveThreads, TimeSpan delayWarningThreshold, TimeSpan activationSchedulingQuantum,
                                     TimeSpan turnWarningLengthThreshold, bool injectMoreWorkerThreads, LimitValue maxPendingItemsLimit)
        {
            Instance = this;
            DelayWarningThreshold = delayWarningThreshold;
            WorkItemGroup.ActivationSchedulingQuantum = activationSchedulingQuantum;
            TurnWarningLengthThreshold = turnWarningLengthThreshold;
            applicationTurnsStopped    = false;
            MaxPendingItemsLimit       = maxPendingItemsLimit;
            workgroupDirectory         = new ConcurrentDictionary <ISchedulingContext, WorkItemGroup>();
            RunQueue = new WorkQueue();
            logger.Info("Starting OrleansTaskScheduler with {0} Max Active application Threads and 1 system thread.", maxActiveThreads);
            Pool = new WorkerPool(this, maxActiveThreads, injectMoreWorkerThreads);
            IntValueStatistic.FindOrCreate(StatisticNames.SCHEDULER_WORKITEMGROUP_COUNT, () => WorkItemGroupCount);
            IntValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_QUEUE_SIZE_INSTANTANEOUS_PER_QUEUE, "Scheduler.LevelOne"), () => RunQueueLength);

            if (!StatisticsCollector.CollectShedulerQueuesStats)
            {
                return;
            }

            FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_QUEUE_SIZE_AVERAGE_PER_QUEUE, "Scheduler.LevelTwo.Average"), () => AverageRunQueueLengthLevelTwo);
            FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_ENQUEUED_PER_QUEUE, "Scheduler.LevelTwo.Average"), () => AverageEnqueuedLevelTwo);
            FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_AVERAGE_ARRIVAL_RATE_PER_QUEUE, "Scheduler.LevelTwo.Average"), () => AverageArrivalRateLevelTwo);
            FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_QUEUE_SIZE_AVERAGE_PER_QUEUE, "Scheduler.LevelTwo.Sum"), () => SumRunQueueLengthLevelTwo);
            FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_ENQUEUED_PER_QUEUE, "Scheduler.LevelTwo.Sum"), () => SumEnqueuedLevelTwo);
            FloatValueStatistic.FindOrCreate(new StatisticName(StatisticNames.QUEUES_AVERAGE_ARRIVAL_RATE_PER_QUEUE, "Scheduler.LevelTwo.Sum"), () => SumArrivalRateLevelTwo);
        }
Esempio n. 2
0
        public void OkClick(object sender, RoutedEventArgs routedEventArgs)
        {
            string path = null;

            if (LimitType == LimitUpString)
            {
                path = "portfolio/setlimitup";
            }
            else if (LimitType == LimitDownString)
            {
                path = "portfolio/setlimitdown";
            }
            APIRequest request = new APIRequest(APIRequest.POST, this, APIRequest.requestCodeType.SetLimit, path);

            Dictionary <string, string> dict = new Dictionary <string, string>()
            {
                { "symbol", Symbol },
                { "limit", LimitValue.ToString("0.000", System.Globalization.CultureInfo.InvariantCulture) }
            };
            var serializer = new DataContractJsonSerializer(dict.GetType(), new DataContractJsonSerializerSettings()
            {
                UseSimpleDictionaryFormat = true
            });
            MemoryStream stream = new MemoryStream();

            serializer.WriteObject(stream, dict);
            byte[] bytes   = stream.ToArray();
            string content = Encoding.UTF8.GetString(bytes, 0, bytes.Length);

            var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
            var token         = localSettings.Values["token"];

            request.Execute((string)token, content);
        }
Esempio n. 3
0
        /// <summary>
        /// Check whether this activation is overloaded.
        /// Returns LimitExceededException if overloaded, otherwise <c>null</c>c>
        /// </summary>
        /// <param name="log">TraceLogger to use for reporting any overflow condition</param>
        /// <returns>Returns LimitExceededException if overloaded, otherwise <c>null</c>c></returns>
        public LimitExceededException CheckOverloaded(TraceLogger log)
        {
            LimitValue limitValue = GetMaxEnqueuedRequestLimit();

            int maxRequestsHardLimit = limitValue.HardLimitThreshold;
            int maxRequestsSoftLimit = limitValue.SoftLimitThreshold;

            if (maxRequestsHardLimit <= 0 && maxRequestsSoftLimit <= 0)
            {
                return(null);                                                        // No limits are set
            }
            int count = GetRequestCount();

            if (maxRequestsHardLimit > 0 && count > maxRequestsHardLimit) // Hard limit
            {
                log.Warn(ErrorCode.Catalog_Reject_ActivationTooManyRequests,
                         String.Format("Overload - {0} enqueued requests for activation {1}, exceeding hard limit rejection threshold of {2}",
                                       count, this, maxRequestsHardLimit));

                return(new LimitExceededException(limitValue.Name, count, maxRequestsHardLimit, this.ToString()));
            }
            if (maxRequestsSoftLimit > 0 && count > maxRequestsSoftLimit) // Soft limit
            {
                log.Warn(ErrorCode.Catalog_Warn_ActivationTooManyRequests,
                         String.Format("Hot - {0} enqueued requests for activation {1}, exceeding soft limit warning threshold of {2}",
                                       count, this, maxRequestsSoftLimit));
                return(null);
            }

            return(null);
        }
Esempio n. 4
0
 public void ReciveDamage(int _value)
 {
     if (LimitValue.IsNegative(_value))
     {
         return;
     }
     unitStatus.helth -= _value;
     if (unitStatus.helth <= 0)
     {
         Destroy(gameObject);
     }
 }
Esempio n. 5
0
        public void Limits_ClientConfig_NotSpecified()
        {
            const string filename = "Config_LogConsumers-ClientConfiguration.xml";
            var          config   = ClientConfiguration.LoadFromFile(filename);

            string     limitName = "NotPresent";
            LimitValue limit     = config.LimitManager.GetLimit(limitName);

            Assert.Equal(0, limit.SoftLimitThreshold);
            Assert.Equal(0, limit.HardLimitThreshold);
            Assert.Equal(limitName, limit.Name);
        }
Esempio n. 6
0
 public void ReciveHeal(int _value)
 {
     if (LimitValue.IsNegative(_value))
     {
         return;
     }
     unitStatus.helth += _value;
     if (unitStatus.helth > maxUnitStatus.helth)
     {
         unitStatus.helth = maxUnitStatus.helth;
     }
 }
Esempio n. 7
0
        private LimitValue GetMaxEnqueuedRequestLimit()
        {
            if (maxEnqueuedRequestsLimit != null)
            {
                return(maxEnqueuedRequestsLimit);
            }
            if (GrainInstanceType != null)
            {
                string limitName = CodeGeneration.GrainInterfaceData.IsStatelessWorker(GrainInstanceType)
                    ? LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER
                    : LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS;
                maxEnqueuedRequestsLimit = LimitManager.GetLimit(limitName); // Cache for next time
                return(maxEnqueuedRequestsLimit);
            }

            return(LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS));
        }
Esempio n. 8
0
        public void Limits_ServerConfig_NotSpecified()
        {
            const string filename      = "Config_LogConsumers-OrleansConfiguration.xml";
            var          orleansConfig = new ClusterConfiguration();

            orleansConfig.LoadFromFile(filename);
            NodeConfiguration config;
            bool hasNodeConfig = orleansConfig.TryGetNodeConfigurationForSilo("Primary", out config);

            Assert.True(hasNodeConfig, "Node Primary has config");

            string     limitName = "NotPresent";
            LimitValue limit     = config.LimitManager.GetLimit(limitName);

            Assert.Equal(0, limit.SoftLimitThreshold);
            Assert.Equal(0, limit.HardLimitThreshold);
            Assert.Equal(limitName, limit.Name);
        }
 protected override void Update()
 {
     ServiceManager.DbConnection.Execute(new HyenaSqliteCommand(@"
         UPDATE CoreSmartPlaylists
             SET Name = ?,
                 Condition = ?,
                 OrderBy = ?,
                 LimitNumber = ?,
                 LimitCriterion = ?,
                 CachedCount = ?,
                 IsTemporary = ?
             WHERE SmartPlaylistID = ?",
                                                                Name, ConditionXml,
                                                                IsLimited ? QueryOrder.Name : null,
                                                                IsLimited ? LimitValue.ToSql() : null,
                                                                IsLimited ? Limit.Name : null,
                                                                Count, IsTemporary, DbId
                                                                ));
     UpdateDependencies();
 }
Esempio n. 10
0
        internal WorkItemGroup(OrleansTaskScheduler sched, ISchedulingContext schedulingContext)
        {
            masterScheduler      = sched;
            SchedulingContext    = schedulingContext;
            state                = WorkGroupStatus.Waiting;
            workItems            = new Queue <Task>();
            lockable             = new Object();
            totalItemsEnQueued   = 0;
            totalItemsProcessed  = 0;
            totalQueuingDelay    = TimeSpan.Zero;
            quantumExpirations   = 0;
            TaskRunner           = new ActivationTaskScheduler(this);
            MaxPendingItemsLimit = LimitManager.GetLimit(LimitNames.LIMIT_MAX_PENDING_ITEMS);
            log = IsSystem ? TraceLogger.GetLogger("Scheduler." + Name + ".WorkItemGroup", TraceLogger.LoggerType.Runtime) : appLogger;

            if (StatisticsCollector.CollectShedulerQueuesStats)
            {
                queueTracking = new QueueTrackingStatistic("Scheduler." + SchedulingContext.Name);
                queueTracking.OnStartExecution();
            }

            if (StatisticsCollector.CollectPerWorkItemStats)
            {
                workItemGroupStatisticsNumber = SchedulerStatisticsGroup.RegisterWorkItemGroup(SchedulingContext.Name, SchedulingContext,
                                                                                               () =>
                {
                    var sb = new StringBuilder();
                    lock (lockable)
                    {
                        sb.Append("QueueLength = " + WorkItemCount);
                        sb.Append(String.Format(", State = {0}", state));
                        if (state == WorkGroupStatus.Runnable)
                        {
                            sb.Append(String.Format("; oldest item is {0} old", workItems.Count >= 0 ? workItems.Peek().ToString() : "null"));
                        }
                    }
                    return(sb.ToString());
                });
            }
        }
Esempio n. 11
0
 public abstract bool IsComplete(LimitValue <float> time);
Esempio n. 12
0
 public override bool IsComplete(LimitValue <float> time)
 {
     return(time.Value <= time.Min);
 }
Esempio n. 13
0
 public override void OnReset(LimitValue <float> time)
 {
     time.Value = time.Max;
 }
Esempio n. 14
0
 public override void OnUpdate(LimitValue <float> time, float deltaTime)
 {
     time.Value -= deltaTime;
 }
Esempio n. 15
0
 protected override void Create()
 {
     DbId = ServiceManager.DbConnection.Execute(new HyenaSqliteCommand(@"
         INSERT INTO CoreSmartPlaylists
             (Name, Condition, OrderBy, LimitNumber, LimitCriterion, PrimarySourceID, IsTemporary, IsHiddenWhenEmpty)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
                                                                       Name, ConditionXml,
                                                                       QueryOrder != null ? QueryOrder.Name : null,
                                                                       IsLimited ? LimitValue.ToSql() : null,
                                                                       IsLimited ? Limit.Name : null,
                                                                       PrimarySourceId, IsTemporary, IsHiddenWhenEmpty
                                                                       ));
     UpdateDependencies();
 }
Esempio n. 16
0
 public abstract void OnUpdate(LimitValue <float> time, float deltaTime);
Esempio n. 17
0
 public abstract void OnReset(LimitValue <float> time);
Esempio n. 18
0
        private static void AddLegacyClusterConfigurationSupport(IServiceCollection services, ClusterConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (services.TryGetClusterConfiguration() != null)
            {
                throw new InvalidOperationException("Cannot configure legacy ClusterConfiguration support twice");
            }

            // these will eventually be removed once our code doesn't depend on the old ClientConfiguration
            services.AddSingleton(configuration);
            services.TryAddSingleton <LegacyConfigurationWrapper>();
            services.TryAddSingleton(sp => sp.GetRequiredService <LegacyConfigurationWrapper>().ClusterConfig.Globals);
            services.TryAddTransient(sp => sp.GetRequiredService <LegacyConfigurationWrapper>().NodeConfig);
            services.TryAddSingleton <Factory <NodeConfiguration> >(
                sp =>
            {
                var initializationParams = sp.GetRequiredService <LegacyConfigurationWrapper>();
                return(() => initializationParams.NodeConfig);
            });

            services.Configure <ClusterOptions>(options =>
            {
                if (string.IsNullOrWhiteSpace(options.ClusterId) && !string.IsNullOrWhiteSpace(configuration.Globals.ClusterId))
                {
                    options.ClusterId = configuration.Globals.ClusterId;
                }

                if (options.ServiceId == Guid.Empty)
                {
                    options.ServiceId = configuration.Globals.ServiceId;
                }
            });

            services.Configure <MultiClusterOptions>(options =>
            {
                var globals = configuration.Globals;
                if (globals.HasMultiClusterNetwork)
                {
                    options.HasMultiClusterNetwork            = true;
                    options.BackgroundGossipInterval          = globals.BackgroundGossipInterval;
                    options.DefaultMultiCluster               = globals.DefaultMultiCluster?.ToList();
                    options.GlobalSingleInstanceNumberRetries = globals.GlobalSingleInstanceNumberRetries;
                    options.GlobalSingleInstanceRetryInterval = globals.GlobalSingleInstanceRetryInterval;
                    options.MaxMultiClusterGateways           = globals.MaxMultiClusterGateways;
                    options.UseGlobalSingleInstanceByDefault  = globals.UseGlobalSingleInstanceByDefault;
                    foreach (GlobalConfiguration.GossipChannelConfiguration channelConfig in globals.GossipChannels)
                    {
                        options.GossipChannels.Add(GlobalConfiguration.Remap(channelConfig.ChannelType), channelConfig.ConnectionString);
                    }
                }
            });

            services.TryAddFromExisting <IMessagingConfiguration, GlobalConfiguration>();

            services.AddOptions <SiloStatisticsOptions>()
            .Configure <NodeConfiguration>((options, nodeConfig) => LegacyConfigurationExtensions.CopyStatisticsOptions(nodeConfig, options))
            .Configure <GlobalConfiguration>((options, config) =>
            {
                options.DeploymentLoadPublisherRefreshTime = config.DeploymentLoadPublisherRefreshTime;
            });

            services.AddOptions <LoadSheddingOptions>()
            .Configure <NodeConfiguration>((options, nodeConfig) =>
            {
                options.LoadSheddingEnabled = nodeConfig.LoadSheddingEnabled;
                options.LoadSheddingLimit   = nodeConfig.LoadSheddingLimit;
            });

            // Translate legacy configuration to new Options
            services.AddOptions <SiloMessagingOptions>()
            .Configure <GlobalConfiguration>((options, config) =>
            {
                LegacyConfigurationExtensions.CopyCommonMessagingOptions(config, options);
                options.SiloSenderQueues                = config.SiloSenderQueues;
                options.GatewaySenderQueues             = config.GatewaySenderQueues;
                options.MaxForwardCount                 = config.MaxForwardCount;
                options.ClientDropTimeout               = config.ClientDropTimeout;
                options.ClientRegistrationRefresh       = config.ClientRegistrationRefresh;
                options.MaxRequestProcessingTime        = config.MaxRequestProcessingTime;
                options.AssumeHomogenousSilosForTesting = config.AssumeHomogenousSilosForTesting;
            })
            .Configure <NodeConfiguration>((options, config) =>
            {
                options.PropagateActivityId            = config.PropagateActivityId;
                LimitValue requestLimit                = config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS);
                options.MaxEnqueuedRequestsSoftLimit   = requestLimit.SoftLimitThreshold;
                options.MaxEnqueuedRequestsHardLimit   = requestLimit.HardLimitThreshold;
                LimitValue statelessWorkerRequestLimit = config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER);
                options.MaxEnqueuedRequestsSoftLimit_StatelessWorker = statelessWorkerRequestLimit.SoftLimitThreshold;
                options.MaxEnqueuedRequestsHardLimit_StatelessWorker = statelessWorkerRequestLimit.HardLimitThreshold;
            });

            services.Configure <NetworkingOptions>(options => LegacyConfigurationExtensions.CopyNetworkingOptions(configuration.Globals, options));

            services.AddOptions <EndpointOptions>()
            .Configure <IOptions <SiloOptions> >((options, siloOptions) =>
            {
                var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName);
                if (!string.IsNullOrEmpty(nodeConfig.HostNameOrIPAddress) || nodeConfig.Port != 0)
                {
                    options.AdvertisedIPAddress = nodeConfig.Endpoint.Address;
                    options.SiloPort            = nodeConfig.Endpoint.Port;
                }
            });

            services.Configure <SerializationProviderOptions>(options =>
            {
                options.SerializationProviders        = configuration.Globals.SerializationProviders;
                options.FallbackSerializationProvider = configuration.Globals.FallbackSerializationProvider;
            });

            services.Configure <TelemetryOptions>(options =>
            {
                LegacyConfigurationExtensions.CopyTelemetryOptions(configuration.Defaults.TelemetryConfiguration, services, options);
            });

            services.AddOptions <GrainClassOptions>().Configure <IOptions <SiloOptions> >((options, siloOptions) =>
            {
                var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName);
                options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes);
            });

            services.AddOptions <SchedulingOptions>()
            .Configure <GlobalConfiguration>((options, config) =>
            {
                options.AllowCallChainReentrancy = config.AllowCallChainReentrancy;
                options.PerformDeadlockDetection = config.PerformDeadlockDetection;
            })
            .Configure <NodeConfiguration>((options, nodeConfig) =>
            {
                options.MaxActiveThreads            = nodeConfig.MaxActiveThreads;
                options.DelayWarningThreshold       = nodeConfig.DelayWarningThreshold;
                options.ActivationSchedulingQuantum = nodeConfig.ActivationSchedulingQuantum;
                options.TurnWarningLengthThreshold  = nodeConfig.TurnWarningLengthThreshold;
                options.EnableWorkerThreadInjection = nodeConfig.EnableWorkerThreadInjection;
                LimitValue itemLimit = nodeConfig.LimitManager.GetLimit(LimitNames.LIMIT_MAX_PENDING_ITEMS);
                options.MaxPendingWorkItemsSoftLimit = itemLimit.SoftLimitThreshold;
                options.MaxPendingWorkItemsHardLimit = itemLimit.HardLimitThreshold;
            });

            services.AddOptions <GrainCollectionOptions>().Configure <GlobalConfiguration>((options, config) =>
            {
                options.CollectionQuantum = config.CollectionQuantum;
                options.CollectionAge     = config.Application.DefaultCollectionAgeLimit;
                foreach (GrainTypeConfiguration grainConfig in config.Application.ClassSpecific)
                {
                    if (grainConfig.CollectionAgeLimit.HasValue)
                    {
                        options.ClassSpecificCollectionAge.Add(grainConfig.FullTypeName, grainConfig.CollectionAgeLimit.Value);
                    }
                }
                ;
            });

            LegacyProviderConfigurator <ISiloLifecycle> .ConfigureServices(configuration.Globals.ProviderConfigurations, services);

            if (!string.IsNullOrWhiteSpace(configuration.Globals.DefaultPlacementStrategy))
            {
                services.AddSingleton(typeof(PlacementStrategy), MapDefaultPlacementStrategy(configuration.Globals.DefaultPlacementStrategy));
            }

            services.AddOptions <ActivationCountBasedPlacementOptions>().Configure <GlobalConfiguration>((options, config) =>
            {
                options.ChooseOutOf = config.ActivationCountBasedPlacementChooseOutOf;
            });

            services.AddOptions <StaticClusterDeploymentOptions>().Configure <ClusterConfiguration>((options, config) =>
            {
                options.SiloNames = config.Overrides.Keys.ToList();
            });

            // add grain service configs as keyed services
            foreach (IGrainServiceConfiguration grainServiceConfiguration in configuration.Globals.GrainServiceConfigurations.GrainServices.Values)
            {
                var type = Type.GetType(grainServiceConfiguration.ServiceType);
                services.AddSingletonKeyedService(type, (sp, k) => grainServiceConfiguration);
            }

            // populate grain service options
            foreach (IGrainServiceConfiguration grainServiceConfiguration in configuration.Globals.GrainServiceConfigurations.GrainServices.Values)
            {
                services.AddGrainService(Type.GetType(grainServiceConfiguration.ServiceType));
            }

            services.AddOptions <ConsistentRingOptions>().Configure <GlobalConfiguration>((options, config) =>
            {
                options.UseVirtualBucketsConsistentRing = config.UseVirtualBucketsConsistentRing;
                options.NumVirtualBucketsConsistentRing = config.NumVirtualBucketsConsistentRing;
            });

            services.AddOptions <ClusterMembershipOptions>()
            .Configure <GlobalConfiguration>((options, config) =>
            {
                options.NumMissedTableIAmAliveLimit = config.NumMissedTableIAmAliveLimit;
                options.LivenessEnabled             = config.LivenessEnabled;
                options.ProbeTimeout                = config.ProbeTimeout;
                options.TableRefreshTimeout         = config.TableRefreshTimeout;
                options.DeathVoteExpirationTimeout  = config.DeathVoteExpirationTimeout;
                options.IAmAliveTablePublishTimeout = config.IAmAliveTablePublishTimeout;
                options.MaxJoinAttemptTime          = config.MaxJoinAttemptTime;
                options.ExpectedClusterSize         = config.ExpectedClusterSize;
                options.ValidateInitialConnectivity = config.ValidateInitialConnectivity;
                options.NumMissedProbesLimit        = config.NumMissedProbesLimit;
                options.UseLivenessGossip           = config.UseLivenessGossip;
                options.NumProbedSilos              = config.NumProbedSilos;
                options.NumVotesForDeathDeclaration = config.NumVotesForDeathDeclaration;
            })
            .Configure <ClusterConfiguration>((options, config) =>
            {
                options.IsRunningAsUnitTest = config.IsRunningAsUnitTest;
            });

            services.AddOptions <GrainVersioningOptions>()
            .Configure <GlobalConfiguration>((options, config) =>
            {
                options.DefaultCompatibilityStrategy   = config.DefaultCompatibilityStrategy?.GetType().Name ?? GrainVersioningOptions.DEFAULT_COMPATABILITY_STRATEGY;
                options.DefaultVersionSelectorStrategy = config.DefaultVersionSelectorStrategy?.GetType().Name ?? GrainVersioningOptions.DEFAULT_VERSION_SELECTOR_STRATEGY;
            });

            services.AddOptions <PerformanceTuningOptions>()
            .Configure <NodeConfiguration>((options, config) =>
            {
                options.DefaultConnectionLimit  = config.DefaultConnectionLimit;
                options.Expect100Continue       = config.Expect100Continue;
                options.UseNagleAlgorithm       = config.UseNagleAlgorithm;
                options.MinDotNetThreadPoolSize = config.MinDotNetThreadPoolSize;
            });

            services.AddOptions <TypeManagementOptions>()
            .Configure <GlobalConfiguration>((options, config) =>
            {
                options.TypeMapRefreshInterval = config.TypeMapRefreshInterval;
            });

            services.AddOptions <GrainDirectoryOptions>()
            .Configure <GlobalConfiguration>((options, config) =>
            {
                options.CachingStrategy         = Remap(config.DirectoryCachingStrategy);
                options.CacheSize               = config.CacheSize;
                options.InitialCacheTTL         = config.InitialCacheTTL;
                options.MaximumCacheTTL         = config.MaximumCacheTTL;
                options.CacheTTLExtensionFactor = config.CacheTTLExtensionFactor;
                options.LazyDeregistrationDelay = config.DirectoryLazyDeregistrationDelay;
            });
        }