Beispiel #1
0
        public int RemoveStaleEntries(uint expirationTime)
        {
            int removedCount = 0;

            lock (this.innerList)
            {
                LinkedListNode <InstanceEndpoint> current = this.innerList.First;
                while (current != null)
                {
                    LinkedListNode <InstanceEndpoint> next = current.Next;

                    InstanceEndpoint instance = current.Value;
                    if (instance.LastRefreshTimestamp < expirationTime)
                    {
                        this.innerList.Remove(current);
                        removedCount++;

                        Debug.WriteLine("UpdateWorkerList: Removed worker {0} from the list.", (object)instance.IPAddress);
                        AntaresEventProvider.EventWriteLBHttpDispatchEndpointInfoMessage(site.Name, instance.IPAddress, "UpdateWorkerList", "Removing worker from routing list");
                    }

                    current = next;
                }
            }

            return(removedCount);
        }
Beispiel #2
0
        internal void SetIsBusy(InstanceEndpoint instance)
        {
            lock (this.innerList)
            {
                uint duration = SiteRequestDispatcher.BusyStatusDuration;
                instance.IsBusyUntil = HttpScaleEnvironment.TickCount + duration;
                instance.IsBusy      = true;

                Debug.WriteLine("Set instance {0} as busy for the next {1}ms. New weight: {2}", instance.IPAddress, duration, instance.Weight);
                AntaresEventProvider.EventWriteLBHttpDispatchEndpointInfoMessage(site.Name, instance.IPAddress, "SetIsBusy", string.Format("Set instance busy for {0}ms. New weight: {1}", duration, instance.Weight));

                // Busy adds a large amount of weight to an instance, moving it towards the back.
                this.UpdatePositionFromBack(instance.Node);
            }
        }
Beispiel #3
0
        internal void ClearBusyStatus(InstanceEndpoint instance)
        {
            lock (this.innerList)
            {
                instance.IsBusy = false;

                // Clearing the busy flag is going to give it a big priority boost,
                // though it's not clear where it will end up. Since most instances will
                // have similar status, it should be safe to assume clearing a busy flag
                // will move it toward the front of the priority list.
                this.UpdatePositionFromFront(instance.Node);

                Debug.WriteLine("Removed busy status from {0}. New weight: {1}", instance.IPAddress, instance.Weight);
                AntaresEventProvider.EventWriteLBHttpDispatchEndpointInfoMessage(site.Name, instance.IPAddress, "ClearBusyStatus", "Removing busy status. New weight: " + instance.Weight);
            }
        }
Beispiel #4
0
        public InstanceEndpoint GetOrAdd(string ipAddress)
        {
            InstanceEndpoint newInstance;

            lock (this.innerList)
            {
                InstanceEndpoint existingInstance;
                if (this.TryGetValueInternal(ipAddress, out existingInstance))
                {
                    return(existingInstance);
                }

                newInstance      = new InstanceEndpoint(ipAddress);
                newInstance.Node = this.innerList.AddFirst(newInstance);
            }

            Debug.WriteLine("UpdateWorkerList: Added worker {0}.", (object)ipAddress);
            AntaresEventProvider.EventWriteLBHttpDispatchEndpointInfoMessage(this.site.Name, ipAddress, "UpdateWorkerList", "Added worker");
            return(newInstance);
        }
        public void OnRequestCompleted(
            string requestId,
            string siteName,
            int statusCode,
            string statusPhrase,
            string ipAddress)
        {
            SiteMetadata site;

            if (!this.knownSites.TryGetValue(siteName, out site))
            {
                throw new ArgumentException(string.Format("Site '{0}' does not exist in the list of known sites.", siteName));
            }

            InstanceEndpoint instance;

            if (!site.Endpoints.TryGetValue(ipAddress, out instance))
            {
                Debug.WriteLine("OnRequestCompleted: Worker '{0}' was not found.", (object)ipAddress);
                AntaresEventProvider.EventWriteLBHttpDispatchEndpointInfoMessage(site.Name, ipAddress, "OnRequestCompleted", "Worker not found");
                return;
            }

            site.Endpoints.OnRequestCompleted(instance);

            // If this is the request we're using as a health sample, clear it so another request can be selected.
            if (instance.HealthTrackingRequestId == requestId)
            {
                instance.HealthTrackingRequestId = null;
            }

            // If the request is rejected because the instance is too busy, mark the endpoint as busy for the next N seconds.
            // This flag will be cleared the next time a request arrives after the busy status expires.
            if (statusCode == 429 && statusPhrase == "Instance Too Busy")
            {
                site.Endpoints.SetIsBusy(instance);
            }
        }