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); }
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); } }
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); } }
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); } }