Example #1
0
        public static int GetCurrentSessions(this ServiceHostBase host)
        {
            ServiceThrottle throttle    = serviceThrottleField.GetValue(host) as ServiceThrottle;
            object          Sessions    = sessionsField.GetValue(throttle);
            int             numSessions = (int)sessionsCountField.GetValue(Sessions);

            return(numSessions);
        }
Example #2
0
        public static int GetCurrentCalls(this ServiceHostBase host)
        {
            ServiceThrottle throttle = serviceThrottleField.GetValue(host) as ServiceThrottle;
            object          Calls    = callsField.GetValue(throttle);
            int             numCalls = (int)callsCountField.GetValue(Calls);

            return(numCalls);
        }
Example #3
0
        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            // Create an instance of the ObjectPoolInstanceProvider.
            ObjectPoolingInstanceProvider instanceProvider = new ObjectPoolingInstanceProvider(description.ServiceType,
                                                                                               minPoolSize);

            // Forward the call if we created a ServiceThrottlingBehavior.
            if (this.throttlingBehavior != null)
            {
                ((IServiceBehavior)this.throttlingBehavior).ApplyDispatchBehavior(description, serviceHostBase);
            }

            // In case there was already a ServiceThrottlingBehavior (this.throttlingBehavior==null),
            // it should have initialized a single ServiceThrottle on all ChannelDispatchers.  As
            // we loop through the ChannelDispatchers, we verify that and modify the ServiceThrottle
            // to guard MaxPoolSize.
            ServiceThrottle throttle = null;

            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                ChannelDispatcher cd = cdb as ChannelDispatcher;
                if (cd != null)
                {
                    // Make sure there is exactly one throttle used by all endpoints.
                    // If there were others, we could not enforce MaxPoolSize.
                    if ((this.throttlingBehavior == null) && (this.maxPoolSize != Int32.MaxValue))
                    {
                        if (throttle == null)
                        {
                            throttle = cd.ServiceThrottle;
                        }
                        if (cd.ServiceThrottle == null)
                        {
                            throw new InvalidOperationException(ResourceHelper.GetString("ExNullThrottle"));
                        }
                        if (throttle != cd.ServiceThrottle)
                        {
                            throw new InvalidOperationException(ResourceHelper.GetString("ExDifferentThrottle"));
                        }
                    }

                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {
                        // Assign it to DispatchBehavior in each endpoint.
                        ed.DispatchRuntime.InstanceProvider = instanceProvider;
                    }
                }
            }

            // Set the MaxConcurrentInstances to limit the number of items that will
            // ever be requested from the pool.
            if ((throttle != null) && (throttle.MaxConcurrentInstances > this.maxPoolSize))
            {
                throttle.MaxConcurrentInstances = this.maxPoolSize;
            }
        }
Example #4
0
        public string  SampleMethod(string msg)
        {
            ServiceThrottle currentThrottle = OperationContext.Current.EndpointDispatcher.ChannelDispatcher.ServiceThrottle;

            Console.WriteLine("Service called. Current throttle values: ");
            Console.WriteLine("MaxConcurrentCalls: {0}.", currentThrottle.MaxConcurrentCalls.ToString());
            Console.WriteLine("MaxConnections: {0}.", currentThrottle.MaxConcurrentSessions.ToString());
            Console.WriteLine("MaxInstances: {0}.", currentThrottle.MaxConcurrentInstances.ToString());
            return("The service greets you: " + msg);
        }
Example #5
0
        protected ServiceHostBase()
        {
            open_timeout  = DefaultOpenTimeout;
            close_timeout = DefaultCloseTimeout;

            credentials         = new ServiceCredentials();
            throttle            = new ServiceThrottle();
            contexts            = new List <InstanceContext> ();
            exposed_contexts    = new ReadOnlyCollection <InstanceContext> (contexts);
            channel_dispatchers = new ChannelDispatcherCollection(this);
        }
Example #6
0
        protected override void OnClosed()
        {
            base.OnClosed();

            ServiceThrottle throttle = this.serviceThrottle;

            if (throttle != null)
            {
                throttle.DeactivateInstanceContext();
            }
        }
Example #7
0
        void Snippet15()
        {
            // <Snippet15>
            Uri         baseAddress = new Uri("http://localhost:8001/Simple");
            ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress);

            serviceHost.AddServiceEndpoint(
                typeof(ICalculator),
                new WSHttpBinding(),
                "CalculatorServiceObject");

            serviceHost.Open();

            IChannelListener  icl        = serviceHost.ChannelDispatchers[0].Listener;
            ChannelDispatcher dispatcher = new ChannelDispatcher(icl);
            ServiceThrottle   throttle   = dispatcher.ServiceThrottle;
            // </Snippet15>
        }
            public ServiceThrottleModel(ServiceThrottle serviceThrottle)
            {
                this.HasThrottle = serviceThrottle != null;

                if (serviceThrottle == null)
                {
                    return;
                }

                this.CallsCount    = serviceThrottle.Calls.Count;
                this.CallsCapacity = serviceThrottle.Calls.Capacity;

                this.SessionsCount    = serviceThrottle.Sessions.Count;
                this.SessionsCapacity = serviceThrottle.Sessions.Capacity;

                this.InstanceContextsCount    = serviceThrottle.InstanceContexts.Count;
                this.InstanceContextsCapacity = serviceThrottle.InstanceContexts.Capacity;
            }
        void IServiceBehavior.ApplyDispatchBehavior(System.ServiceModel.Description.ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            if (serviceHostBase == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("serviceHostBase"));
            }
            ServiceThrottle serviceThrottle = serviceHostBase.ServiceThrottle;

            serviceThrottle.MaxConcurrentCalls     = this.calls;
            serviceThrottle.MaxConcurrentSessions  = this.sessions;
            serviceThrottle.MaxConcurrentInstances = this.MaxConcurrentInstances;
            for (int i = 0; i < serviceHostBase.ChannelDispatchers.Count; i++)
            {
                ChannelDispatcher dispatcher = serviceHostBase.ChannelDispatchers[i] as ChannelDispatcher;
                if (dispatcher != null)
                {
                    dispatcher.ServiceThrottle = serviceThrottle;
                }
            }
        }
        private ChannelDispatcher EnsureGetDispatcher(ServiceHostBase host, ServiceMetadataExtension mex, Uri listenUri)
        {
            const string ServiceHealthBehaviorHttpGetBinding = "ServiceHealthBehaviorHttpGetBinding";

            ChannelDispatcher channelDispatcher = mex.FindGetDispatcher(listenUri);

            Binding binding;

            if (channelDispatcher == null)
            {
                if (listenUri.Scheme == Uri.UriSchemeHttp)
                {
                    binding = this.HttpGetBinding ?? MetadataExchangeBindings.HttpGet;
                }
                else if (listenUri.Scheme == Uri.UriSchemeHttps)
                {
                    binding = this.HttpsGetBinding ?? MetadataExchangeBindings.HttpsGet;
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxGetChannelDispatcherDoesNotSupportScheme, nameof(ChannelDispatcher), Uri.UriSchemeHttp, Uri.UriSchemeHttps)));
                }

                channelDispatcher = mex.CreateGetDispatcher(listenUri, binding, ServiceHealthBehaviorHttpGetBinding);

                host.ChannelDispatchers.Add(channelDispatcher);
            }

            if (host.ServiceThrottle != null)
            {
                ServiceThrottle throttle = new ServiceThrottle(host);
                throttle.MaxConcurrentCalls       = host.ServiceThrottle.Calls.Capacity;
                throttle.MaxConcurrentSessions    = host.ServiceThrottle.Sessions.Capacity;
                throttle.MaxConcurrentInstances   = host.ServiceThrottle.InstanceContexts.Capacity;
                channelDispatcher.ServiceThrottle = throttle;
            }

            channelDispatcher.IsServiceThrottleReplaced = true;

            return(channelDispatcher);
        }
        protected virtual HttpStatusCode GetHttpResponseCode(ServiceHostBase serviceHost, string[] queries)
        {
            const string OnServiceFailure          = "OnServiceFailure";
            const string OnDispatcherFailure       = "OnDispatcherFailure";
            const string OnListenerFailure         = "OnListenerFailure";
            const string OnThrottlePercentExceeded = "OnThrottlePercentExceeded";

            const HttpStatusCode defaultErrorCode = HttpStatusCode.ServiceUnavailable;

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

            if (queries == null || queries.Length == 0)
            {
                return(HttpStatusCode.OK);
            }

            bool           useDefaultSettings = true;
            HttpStatusCode resultCode;

            for (int i = 0; i < queries.Length; i++)
            {
                if (TryParseHttpStatusCodeQueryParameter(OnServiceFailure, queries[i], defaultErrorCode, out resultCode))
                {
                    useDefaultSettings = false;
                    if (serviceHost.State > CommunicationState.Opened)
                    {
                        return(resultCode);
                    }
                }
                else if (TryParseHttpStatusCodeQueryParameter(OnDispatcherFailure, queries[i], defaultErrorCode, out resultCode))
                {
                    useDefaultSettings = false;
                    if (serviceHost.ChannelDispatchers != null)
                    {
                        foreach (var dispatcherBase in serviceHost.ChannelDispatchers)
                        {
                            ChannelDispatcher dispatcher = dispatcherBase as ChannelDispatcher;

                            if (dispatcher != null && dispatcher.State > CommunicationState.Opened)
                            {
                                return(resultCode);
                            }
                        }
                    }
                }
                else if (TryParseHttpStatusCodeQueryParameter(OnListenerFailure, queries[i], defaultErrorCode, out resultCode))
                {
                    useDefaultSettings = false;
                    if (serviceHost.ChannelDispatchers != null)
                    {
                        foreach (var dispatcherBase in serviceHost.ChannelDispatchers)
                        {
                            if (dispatcherBase.Listener != null && dispatcherBase.Listener.State > CommunicationState.Opened)
                            {
                                return(resultCode);
                            }
                        }
                    }
                }
                else
                {
                    string[] kvp = queries[i].Split('=');

                    if (serviceHost.ServiceThrottle != null && string.Compare(kvp[0], OnThrottlePercentExceeded, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        useDefaultSettings = false;

                        if (kvp.Length == 2)
                        {
                            //OnThrottlePercentExceeded always expects a value.

                            string key   = kvp[0];
                            string value = kvp[1];

                            string[] throttleValues =
                                value.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries);

                            int qsPercent;
                            int qsStatusCode;
                            SortedDictionary <int, int> throttles = new SortedDictionary <int, int>(descendingComparer);

                            foreach (string v in throttleValues)
                            {
                                string[] percentThrottlePair = v.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);

                                if (percentThrottlePair.Length == 1)
                                {
                                    //Add default error code if only a percentage was added.
                                    percentThrottlePair = new string[] { percentThrottlePair[0], ((int)defaultErrorCode).ToString() };
                                }

                                if (percentThrottlePair.Length == 2 && int.TryParse(percentThrottlePair[0], out qsPercent) && qsPercent >= 0 && qsPercent <= 100)
                                {
                                    if (!throttles.ContainsKey(qsPercent))
                                    {
                                        if (!int.TryParse(percentThrottlePair[1], out qsStatusCode) || !EnsureHttpStatusCode(qsStatusCode))
                                        {
                                            qsStatusCode = (int)defaultErrorCode;
                                        }

                                        throttles.Add(qsPercent, qsStatusCode);
                                    }
                                }
                            }

                            if (throttles.Count > 0)
                            {
                                ServiceThrottle throttle         = serviceHost.ServiceThrottle;
                                int             callsPercent     = throttle.Calls.Capacity == 0 ? 0 : throttle.Calls.Count * 100 / throttle.Calls.Capacity;
                                int             sessionsPercent  = throttle.Sessions.Capacity == 0 ? 0 : throttle.Sessions.Count * 100 / throttle.Sessions.Capacity;
                                int             instancesPercent = throttle.InstanceContexts.Capacity == 0 ? 0 : throttle.InstanceContexts.Count * 100 / throttle.InstanceContexts.Capacity;

                                foreach (KeyValuePair <int, int> throttleKvp in throttles)
                                {
                                    int percent = throttleKvp.Key;
                                    int code    = throttleKvp.Value;

                                    if (callsPercent >= percent || sessionsPercent >= percent || instancesPercent >= percent)
                                    {
                                        return((HttpStatusCode)code);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (useDefaultSettings)
            {
                bool hasError = useDefaultSettings && serviceHost.State > CommunicationState.Opened;

                if (!hasError)
                {
                    if (serviceHost.ChannelDispatchers != null)
                    {
                        foreach (var dispatcherBase in serviceHost.ChannelDispatchers)
                        {
                            ChannelDispatcher dispatcher = dispatcherBase as ChannelDispatcher;

                            if ((dispatcherBase.Listener != null && dispatcherBase.Listener.State > CommunicationState.Opened) ||
                                (dispatcher != null && dispatcher.State > CommunicationState.Opened))
                            {
                                hasError = true;
                                break;
                            }
                        }
                    }
                }

                if (hasError)
                {
                    return(defaultErrorCode);
                }
            }

            return(HttpStatusCode.OK);
        }