private int GetPrioritisedQueuePosition(int insertingItemPriority) { // Assume the back of the queue will be where we insert it. int targetQueuePosition = Count; // Items with priority zero always get added to the end of the queue, as will anything if the // queue only has one item in it as we assume that item is integrating already and cannot be moved. if (insertingItemPriority != 0 && Count > 1) { for (int index = 1; index < Count; index++) { IIntegrationQueueItem queuedIntegrationQueueItem = this[index] as IIntegrationQueueItem; if (queuedIntegrationQueueItem != null) { int compareQueuePosition = queuedIntegrationQueueItem.Project.QueuePriority; // If two items have the same priority it will be FIFO order for that priority if (compareQueuePosition == 0 || compareQueuePosition > insertingItemPriority) { targetQueuePosition = index; break; } } } } return(targetQueuePosition); }
public void SetUp() { integrationQueues = new IntegrationQueueSet(); integrationQueues.Add(TestQueueName, new DefaultQueueConfiguration(TestQueueName)); integrationQueues.Add(TestQueueName2, new DefaultQueueConfiguration(TestQueueName2)); integrationQueue1 = integrationQueues[TestQueueName]; integrationQueue2 = integrationQueues[TestQueueName2]; integrationRequest = new IntegrationRequest(BuildCondition.ForceBuild, "Test", null); project1Mock = new Mock <IProject>(MockBehavior.Strict); project1Mock.SetupGet(project => project.Name).Returns("ProjectOne"); project1Mock.SetupGet(project => project.QueueName).Returns(TestQueueName); project1Mock.SetupGet(project => project.QueuePriority).Returns(0); project2Mock = new Mock <IProject>(MockBehavior.Strict); project2Mock.SetupGet(project => project.Name).Returns("ProjectTwo"); project2Mock.SetupGet(project => project.QueueName).Returns(TestQueueName2); project2Mock.SetupGet(project => project.QueuePriority).Returns(0); queueNotifier1Mock = new Mock <IIntegrationQueueNotifier>(MockBehavior.Strict); queueNotifier2Mock = new Mock <IIntegrationQueueNotifier>(MockBehavior.Strict); integrationQueueItem1 = new IntegrationQueueItem((IProject)project1Mock.Object, integrationRequest, (IIntegrationQueueNotifier)queueNotifier1Mock.Object); integrationQueueItem2 = new IntegrationQueueItem((IProject)project2Mock.Object, integrationRequest, (IIntegrationQueueNotifier)queueNotifier2Mock.Object); }
public void SetUp() { integrationQueues = new IntegrationQueueSet(); integrationQueues.Add(TestQueueName, new DefaultQueueConfiguration(TestQueueName)); integrationQueues.Add(TestQueueName2, new DefaultQueueConfiguration(TestQueueName2)); integrationQueue1 = integrationQueues[TestQueueName]; integrationQueue2 = integrationQueues[TestQueueName2]; integrationRequest = new IntegrationRequest(BuildCondition.ForceBuild, "Test", null); project1Mock = new LatchMock(typeof(IProject)); project1Mock.Strict = true; project1Mock.SetupResult("Name", "ProjectOne"); project1Mock.SetupResult("QueueName", TestQueueName); project1Mock.SetupResult("QueuePriority", 0); project2Mock = new LatchMock(typeof(IProject)); project2Mock.Strict = true; project2Mock.SetupResult("Name", "ProjectTwo"); project2Mock.SetupResult("QueueName", TestQueueName2); project2Mock.SetupResult("QueuePriority", 0); queueNotifier1Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier1Mock.Strict = true; queueNotifier2Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier2Mock.Strict = true; integrationQueueItem1 = new IntegrationQueueItem((IProject)project1Mock.MockInstance, integrationRequest, (IIntegrationQueueNotifier)queueNotifier1Mock.MockInstance); integrationQueueItem2 = new IntegrationQueueItem((IProject)project2Mock.MockInstance, integrationRequest, (IIntegrationQueueNotifier)queueNotifier2Mock.MockInstance); }
private void AddToQueue(IIntegrationQueueItem integrationQueueItem, int?queuePosition) { if (!queuePosition.HasValue) { queuePosition = GetPrioritisedQueuePosition(integrationQueueItem.Project.QueuePriority); Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: '{0}' is added to queue: '{1}' in position {2}. Requestsource : {3} ({4})", integrationQueueItem.Project.Name, Name, queuePosition, integrationQueueItem.IntegrationRequest.Source, integrationQueueItem.IntegrationRequest.UserName)); } integrationQueueItem.IntegrationQueueNotifier.NotifyEnteringIntegrationQueue(); Insert(queuePosition.Value, integrationQueueItem); }
/// <summary> /// Releases the next integration request on the queue to start it's integration. /// </summary> public void Dequeue() { lock (this) { if (Count > 0) { // The first item in the queue has now been integrated so discard it. IIntegrationQueueItem integrationQueueItem = (IIntegrationQueueItem)this[0]; NotifyExitingQueueAndRemoveItem(0, integrationQueueItem, false); } } }
private void RemoveProjectItems(IProject project, bool considerFirstQueueItem) { // Note we are also potentially removing the item at index[0] as this method should // only be called when the thread performing the build has been stopped. int startQueueIndex = considerFirstQueueItem ? 0 : 1; for (int index = Count - 1; index >= startQueueIndex; index--) { IIntegrationQueueItem integrationQueueItem = (IIntegrationQueueItem)this[index]; if (integrationQueueItem.Project.Equals(project)) { Log.Info("Project: " + integrationQueueItem.Project.Name + " removed from queue: " + Name); bool isPendingItemCancelled = index > 0; NotifyExitingQueueAndRemoveItem(index, integrationQueueItem, isPendingItemCancelled); } } }
private bool HasItemOnQueue(IProject project, bool pendingItemsOnly) { lock (this) { int startIndex = pendingItemsOnly ? 1 : 0; if (Count > startIndex) { for (int index = startIndex; index < Count; index++) { IIntegrationQueueItem queuedIntegrationQueueItem = this[index] as IIntegrationQueueItem; if ((queuedIntegrationQueueItem != null) && (queuedIntegrationQueueItem.Project == project)) { return(true); } } } return(false); } }
private static QueueSnapshot BuildQueueSnapshot(IIntegrationQueue queue) { QueueSnapshot queueSnapshot = new QueueSnapshot(queue.Name); for (int index = 0; index < queue.Count; index++) { IIntegrationQueueItem integrationQueueItem = (IIntegrationQueueItem)queue[index]; // The first request in the queue shows it's real activity of CheckingModifications or Building // Everything else is in a pending state. ProjectActivity projectActivity = ProjectActivity.Pending; if (index == 0) { projectActivity = integrationQueueItem.Project.CurrentActivity; } QueuedRequestSnapshot queuedRequestSnapshot = new QueuedRequestSnapshot( integrationQueueItem.Project.Name, projectActivity, integrationQueueItem.IntegrationRequest.RequestTime); queueSnapshot.Requests.Add(queuedRequestSnapshot); } return(queueSnapshot); }
/// <summary> /// Gets the next request. /// </summary> /// <param name="project">The project.</param> /// <returns></returns> /// <remarks></remarks> public IntegrationRequest GetNextRequest(IProject project) { lock (this) { if (Count == 0) { return(null); } if (IsBlocked) { return(null); } IIntegrationQueueItem item = GetIntegrationQueueItem(0); if (item != null && item.Project == project) { return(item.IntegrationRequest); } return(null); } }
public void SetUp() { integrationQueues = new IntegrationQueueSet(); integrationQueues.Add(TestQueueName, new DefaultQueueConfiguration(TestQueueName)); integrationQueueUseFirst = integrationQueues[TestQueueName]; // Generate a queue to test re-adding string secondQueueName = "Test Queue #2"; IQueueConfiguration readConfig = new DefaultQueueConfiguration(secondQueueName); readConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReAdd; integrationQueues.Add(secondQueueName, readConfig); integrationQueueReAdd = integrationQueues[secondQueueName]; // Generate a queue to test re-adding to top var fourthQueueName = "Test Queue #4"; var raddTopConfig = new DefaultQueueConfiguration(fourthQueueName); raddTopConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReAddTop; integrationQueues.Add(fourthQueueName, raddTopConfig); integrationQueueReAddTop = integrationQueues[fourthQueueName]; // Generate a queue to test replacing string thirdQueueName = "Test Queue #3"; IQueueConfiguration replaceConfig = new DefaultQueueConfiguration(thirdQueueName); replaceConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReplace; integrationQueues.Add(thirdQueueName, replaceConfig); integrationQueueReplace = integrationQueues[thirdQueueName]; integrationRequestForceBuild = new IntegrationRequest(BuildCondition.ForceBuild, "Test", null); integrationRequestIfModificationExists = new IntegrationRequest(BuildCondition.IfModificationExists, "Test", null); project1Mock = new Mock <IProject>(MockBehavior.Strict); project1Mock.SetupGet(project => project.Name).Returns("ProjectOne"); project1Mock.SetupGet(project => project.QueueName).Returns(TestQueueName); project1Mock.SetupGet(project => project.QueuePriority).Returns(0); project2Mock = new Mock <IProject>(MockBehavior.Strict); project2Mock.SetupGet(project => project.Name).Returns("ProjectTwo"); project2Mock.SetupGet(project => project.QueueName).Returns(TestQueueName); project2Mock.SetupGet(project => project.QueuePriority).Returns(0); project3Mock = new Mock <IProject>(MockBehavior.Strict); project3Mock.SetupGet(project => project.Name).Returns("ProjectThree"); project3Mock.SetupGet(project => project.QueueName).Returns(TestQueueName); project3Mock.SetupGet(project => project.QueuePriority).Returns(1); queueNotifier1Mock = new Mock <IIntegrationQueueNotifier>(MockBehavior.Strict); queueNotifier2Mock = new Mock <IIntegrationQueueNotifier>(MockBehavior.Strict); queueNotifier3Mock = new Mock <IIntegrationQueueNotifier>(MockBehavior.Strict); integrationQueueItem1 = new IntegrationQueueItem((IProject)project1Mock.Object, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier1Mock.Object); integrationQueueItem2 = new IntegrationQueueItem((IProject)project2Mock.Object, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier2Mock.Object); integrationQueueItem3 = new IntegrationQueueItem((IProject)project3Mock.Object, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier3Mock.Object); integrationQueueItem4 = new IntegrationQueueItem((IProject)project2Mock.Object, integrationRequestIfModificationExists, (IIntegrationQueueNotifier)queueNotifier2Mock.Object); }
/// <summary> /// Add a project integration request be added to the integration queue. /// If no requests are on that queue already the integration is just kicked off immediately. /// If the request is a force build and an integration is already on the queue for that project /// then the queue request is ignored as it is redundant. /// </summary> /// <param name="integrationQueueItem">The integration queue item.</param> public void Enqueue(IIntegrationQueueItem integrationQueueItem) { lock (this) { if (Count == 0) { // We can start integration straight away as first in first served AddToQueue(integrationQueueItem); } else { // We need to see if we already have a integration request for this project on the queue // If so then we will ignore the latest request. // Note we start at queue position 1 since position 0 is currently integrating. int? foundIndex = null; bool addItem = true; IIntegrationQueueItem foundItem = null; for (int index = 1; index < Count; index++) { IIntegrationQueueItem queuedItem = GetIntegrationQueueItem(index); if (queuedItem.Project == integrationQueueItem.Project) { foundItem = queuedItem; foundIndex = index; break; } } if (foundIndex != null) { switch (configuration.HandlingMode) { case QueueDuplicateHandlingMode.UseFirst: // Only use the first item in the queue - if a newer item is added it will be ignored Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); addItem = false; break; case QueueDuplicateHandlingMode.ApplyForceBuildsReAdd: // If a force build is added to the queue, it will remove an existing non-force build and add the new request to the end of the queue if (foundItem.IntegrationRequest.BuildCondition >= integrationQueueItem.IntegrationRequest.BuildCondition) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); addItem = false; } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} with lower prority - cancelling existing request", integrationQueueItem.Project.Name, Name)); lock (this) { NotifyExitingQueueAndRemoveItem(foundIndex.Value, foundItem, true); } } break; case QueueDuplicateHandlingMode.ApplyForceBuildsReAddTop: // If a force build is added to the queue, it will remove an existing non-force build and add the new request to the beginning of the queue addItem = false; if (foundItem.IntegrationRequest.BuildCondition >= integrationQueueItem.IntegrationRequest.BuildCondition) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} with lower prority - cancelling existing request", integrationQueueItem.Project.Name, Name)); lock (this) { NotifyExitingQueueAndRemoveItem(foundIndex.Value, foundItem, true); // Add project to the queue directly after the currently building one. AddToQueue(integrationQueueItem, 1); } } break; case QueueDuplicateHandlingMode.ApplyForceBuildsReplace: // If a force build is added to the queue, it will replace an existing non-forc build addItem = false; if (foundItem.IntegrationRequest.BuildCondition >= integrationQueueItem.IntegrationRequest.BuildCondition) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: {0} already on queue: {1} with lower prority - replacing existing request at position {2}", integrationQueueItem.Project.Name, Name, foundIndex)); lock (this) { NotifyExitingQueueAndRemoveItem(foundIndex.Value, foundItem, true); AddToQueue(integrationQueueItem, foundIndex); } } break; default: throw new ConfigurationException("Unknown handling mode for duplicates: " + configuration.HandlingMode); } } if (addItem) { lock (this) { AddToQueue(integrationQueueItem); } } } } }
private void NotifyExitingQueueAndRemoveItem(int index, IIntegrationQueueItem integrationQueueItem, bool isPendingItemCancelled) { integrationQueueItem.IntegrationQueueNotifier.NotifyExitingIntegrationQueue(isPendingItemCancelled); RemoveAt(index); }
/// <summary> /// Will find a Service Registered to process the item. /// </summary> public static async Task <IIntegrationQueueItem> Process(IIntegrationQueueItem item) { if (item.ResponseDate.HasValue) { return(item); // Already processed: } #region Pick the item Type serviceType; using (await PickLock.Lock()) { if (item.DatePicked.HasValue) { // Already picked, let the other thread finish its job: return(null); } if (!item.IsNew) { item = (IIntegrationQueueItem)item.Clone(); } serviceType = IntegrationServices.GetOrDefault(item.IntegrationService); if (serviceType == null) { return(null); } item.DatePicked = LocalTime.Now; await Entity.Database.Save(item); item = (IIntegrationQueueItem)(await Entity.Database.Reload(item)).Clone(); } // TOOD: This is not thread safe in multi-server (web farm) scenarios. // To make it completely safe, we need a single StoredProc or SQL command that will do both at the same time, with a lock at the DB level. #endregion var service = serviceType.CreateInstance(); var serviceInterface = serviceType.GetInterfaces().Single(x => x.Name.Contains("IServiceImplementor")); var typeOfRequest = serviceInterface.GetGenericArguments().First(); var request = JsonConvert.DeserializeObject(item.Request, typeOfRequest); var method = serviceType.GetMethod("GetResponse", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); try { var response = method.Invoke(service, new[] { request }); item.Response = JsonConvert.SerializeObject(response); } catch (Exception ex) { item.ErrorResponse = ex.ToString(); } item.ResponseDate = LocalTime.Now; await Entity.Database.Save(item); return(item); }
public static bool IsInProcess(this IIntegrationQueueItem item) => item.DatePicked != null;
public void SetUp() { integrationQueues = new IntegrationQueueSet(); integrationQueues.Add(TestQueueName, new DefaultQueueConfiguration(TestQueueName)); integrationQueues.Add(TestQueueName2, new DefaultQueueConfiguration(TestQueueName2)); integrationQueue1 = integrationQueues[TestQueueName]; integrationQueue2 = integrationQueues[TestQueueName2]; integrationRequest = new IntegrationRequest(BuildCondition.ForceBuild, "Test", null); project1Mock = new LatchMock(typeof (IProject)); project1Mock.Strict = true; project1Mock.SetupResult("Name", "ProjectOne"); project1Mock.SetupResult("QueueName", TestQueueName); project1Mock.SetupResult("QueuePriority", 0); project2Mock = new LatchMock(typeof (IProject)); project2Mock.Strict = true; project2Mock.SetupResult("Name", "ProjectTwo"); project2Mock.SetupResult("QueueName", TestQueueName2); project2Mock.SetupResult("QueuePriority", 0); queueNotifier1Mock = new LatchMock(typeof (IIntegrationQueueNotifier)); queueNotifier1Mock.Strict = true; queueNotifier2Mock = new LatchMock(typeof (IIntegrationQueueNotifier)); queueNotifier2Mock.Strict = true; integrationQueueItem1 = new IntegrationQueueItem((IProject) project1Mock.MockInstance, integrationRequest, (IIntegrationQueueNotifier) queueNotifier1Mock.MockInstance); integrationQueueItem2 = new IntegrationQueueItem((IProject) project2Mock.MockInstance, integrationRequest, (IIntegrationQueueNotifier) queueNotifier2Mock.MockInstance); }
private void AddToQueue(IIntegrationQueueItem integrationQueueItem) { AddToQueue(integrationQueueItem, null); }
public static bool IsProcessed(this IIntegrationQueueItem item) { return(item.ResponseDate != null); }
public void SetUp() { integrationQueues = new IntegrationQueueSet(); integrationQueues.Add(TestQueueName, new DefaultQueueConfiguration(TestQueueName)); integrationQueueUseFirst = integrationQueues[TestQueueName]; // Generate a queue to test re-adding string secondQueueName = "Test Queue #2"; IQueueConfiguration readConfig = new DefaultQueueConfiguration(secondQueueName); readConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReAdd; integrationQueues.Add(secondQueueName, readConfig); integrationQueueReAdd = integrationQueues[secondQueueName]; // Generate a queue to test re-adding to top var fourthQueueName = "Test Queue #4"; var raddTopConfig = new DefaultQueueConfiguration(fourthQueueName); raddTopConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReAddTop; integrationQueues.Add(fourthQueueName, raddTopConfig); integrationQueueReAddTop = integrationQueues[fourthQueueName]; // Generate a queue to test replacing string thirdQueueName = "Test Queue #3"; IQueueConfiguration replaceConfig = new DefaultQueueConfiguration(thirdQueueName); replaceConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReplace; integrationQueues.Add(thirdQueueName, replaceConfig); integrationQueueReplace = integrationQueues[thirdQueueName]; integrationRequestForceBuild = new IntegrationRequest(BuildCondition.ForceBuild, "Test", null); integrationRequestIfModificationExists = new IntegrationRequest(BuildCondition.IfModificationExists, "Test", null); project1Mock = new LatchMock(typeof (IProject)); project1Mock.Strict = true; project1Mock.SetupResult("Name", "ProjectOne"); project1Mock.SetupResult("QueueName", TestQueueName); project1Mock.SetupResult("QueuePriority", 0); project2Mock = new LatchMock(typeof (IProject)); project2Mock.Strict = true; project2Mock.SetupResult("Name", "ProjectTwo"); project2Mock.SetupResult("QueueName", TestQueueName); project2Mock.SetupResult("QueuePriority", 0); project3Mock = new LatchMock(typeof (IProject)); project3Mock.Strict = true; project3Mock.SetupResult("Name", "ProjectThree"); project3Mock.SetupResult("QueueName", TestQueueName); project3Mock.SetupResult("QueuePriority", 1); queueNotifier1Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier1Mock.Strict = true; queueNotifier2Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier2Mock.Strict = true; queueNotifier3Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier3Mock.Strict = true; integrationQueueItem1 = new IntegrationQueueItem((IProject)project1Mock.MockInstance, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier1Mock.MockInstance); integrationQueueItem2 = new IntegrationQueueItem((IProject)project2Mock.MockInstance, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier2Mock.MockInstance); integrationQueueItem3 = new IntegrationQueueItem((IProject)project3Mock.MockInstance, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier3Mock.MockInstance); integrationQueueItem4 = new IntegrationQueueItem((IProject)project2Mock.MockInstance, integrationRequestIfModificationExists, (IIntegrationQueueNotifier)queueNotifier2Mock.MockInstance); }
public static bool IsInProcess(this IIntegrationQueueItem item) { return(item.DatePicked != null); }
public void SetUp() { integrationQueues = new IntegrationQueueSet(); integrationQueues.Add(TestQueueName, new DefaultQueueConfiguration(TestQueueName)); integrationQueueUseFirst = integrationQueues[TestQueueName]; // Generate a queue to test re-adding string secondQueueName = "Test Queue #2"; IQueueConfiguration readConfig = new DefaultQueueConfiguration(secondQueueName); readConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReAdd; integrationQueues.Add(secondQueueName, readConfig); integrationQueueReAdd = integrationQueues[secondQueueName]; // Generate a queue to test re-adding to top var fourthQueueName = "Test Queue #4"; var raddTopConfig = new DefaultQueueConfiguration(fourthQueueName); raddTopConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReAddTop; integrationQueues.Add(fourthQueueName, raddTopConfig); integrationQueueReAddTop = integrationQueues[fourthQueueName]; // Generate a queue to test replacing string thirdQueueName = "Test Queue #3"; IQueueConfiguration replaceConfig = new DefaultQueueConfiguration(thirdQueueName); replaceConfig.HandlingMode = QueueDuplicateHandlingMode.ApplyForceBuildsReplace; integrationQueues.Add(thirdQueueName, replaceConfig); integrationQueueReplace = integrationQueues[thirdQueueName]; integrationRequestForceBuild = new IntegrationRequest(BuildCondition.ForceBuild, "Test", null); integrationRequestIfModificationExists = new IntegrationRequest(BuildCondition.IfModificationExists, "Test", null); project1Mock = new LatchMock(typeof(IProject)); project1Mock.Strict = true; project1Mock.SetupResult("Name", "ProjectOne"); project1Mock.SetupResult("QueueName", TestQueueName); project1Mock.SetupResult("QueuePriority", 0); project2Mock = new LatchMock(typeof(IProject)); project2Mock.Strict = true; project2Mock.SetupResult("Name", "ProjectTwo"); project2Mock.SetupResult("QueueName", TestQueueName); project2Mock.SetupResult("QueuePriority", 0); project3Mock = new LatchMock(typeof(IProject)); project3Mock.Strict = true; project3Mock.SetupResult("Name", "ProjectThree"); project3Mock.SetupResult("QueueName", TestQueueName); project3Mock.SetupResult("QueuePriority", 1); queueNotifier1Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier1Mock.Strict = true; queueNotifier2Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier2Mock.Strict = true; queueNotifier3Mock = new LatchMock(typeof(IIntegrationQueueNotifier)); queueNotifier3Mock.Strict = true; integrationQueueItem1 = new IntegrationQueueItem((IProject)project1Mock.MockInstance, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier1Mock.MockInstance); integrationQueueItem2 = new IntegrationQueueItem((IProject)project2Mock.MockInstance, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier2Mock.MockInstance); integrationQueueItem3 = new IntegrationQueueItem((IProject)project3Mock.MockInstance, integrationRequestForceBuild, (IIntegrationQueueNotifier)queueNotifier3Mock.MockInstance); integrationQueueItem4 = new IntegrationQueueItem((IProject)project2Mock.MockInstance, integrationRequestIfModificationExists, (IIntegrationQueueNotifier)queueNotifier2Mock.MockInstance); }
/// <summary> /// Add a project integration request be added to the integration queue. /// If no requests are on that queue already the integration is just kicked off immediately. /// If the request is a force build and an integration is already on the queue for that project /// then the queue request is ignored as it is redundant. /// </summary> /// <param name="integrationQueueItem">The integration queue item.</param> public void Enqueue(IIntegrationQueueItem integrationQueueItem) { lock (this) { if (Count == 0) { // We can start integration straight away as first in first served AddToQueue(integrationQueueItem); } else { // We need to see if we already have a integration request for this project on the queue // If so then we will ignore the latest request. // Note we start at queue position 1 since position 0 is currently integrating. int? foundIndex = null; bool addItem = true; IIntegrationQueueItem foundItem = null; for (int index = 1; index < Count; index++) { IIntegrationQueueItem queuedItem = GetIntegrationQueueItem(index); if (queuedItem.Project == integrationQueueItem.Project) { foundItem = queuedItem; foundIndex = index; break; } } if (foundIndex != null) { switch (configuration.HandlingMode) { case QueueDuplicateHandlingMode.UseFirst: // Only use the first item in the queue - if a newer item is added it will be ignored Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); addItem = false; break; case QueueDuplicateHandlingMode.ApplyForceBuildsReAdd: // If a force build is added to the queue, it will remove an existing non-force build and add the new request to the end of the queue if (foundItem.IntegrationRequest.BuildCondition >= integrationQueueItem.IntegrationRequest.BuildCondition) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); addItem = false; } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} with lower prority - cancelling existing request", integrationQueueItem.Project.Name, Name)); lock (this) { NotifyExitingQueueAndRemoveItem(foundIndex.Value, foundItem, true); } } break; case QueueDuplicateHandlingMode.ApplyForceBuildsReAddTop: // If a force build is added to the queue, it will remove an existing non-force build and add the new request to the beginning of the queue addItem = false; if (foundItem.IntegrationRequest.BuildCondition >= integrationQueueItem.IntegrationRequest.BuildCondition) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} with lower prority - cancelling existing request", integrationQueueItem.Project.Name, Name)); lock (this) { NotifyExitingQueueAndRemoveItem(foundIndex.Value, foundItem, true); // Add project to the queue directly after the currently building one. AddToQueue(integrationQueueItem, 1); } } break; case QueueDuplicateHandlingMode.ApplyForceBuildsReplace: // If a force build is added to the queue, it will replace an existing non-forc build addItem = false; if (foundItem.IntegrationRequest.BuildCondition >= integrationQueueItem.IntegrationRequest.BuildCondition) { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} - cancelling new request", integrationQueueItem.Project.Name, Name)); } else { Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: {0} already on queue: {1} with lower prority - replacing existing request at position {2}", integrationQueueItem.Project.Name, Name, foundIndex)); lock (this) { NotifyExitingQueueAndRemoveItem(foundIndex.Value, foundItem, true); AddToQueue(integrationQueueItem, foundIndex); } } break; default: throw new ConfigurationException("Unknown handling mode for duplicates: " + configuration.HandlingMode); } } if (addItem) { lock (this) { AddToQueue(integrationQueueItem); } } } } }
private void AddToQueue(IIntegrationQueueItem integrationQueueItem, int? queuePosition) { if (!queuePosition.HasValue) { queuePosition = GetPrioritisedQueuePosition(integrationQueueItem.Project.QueuePriority); Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Project: '{0}' is added to queue: '{1}' in position {2}. Requestsource : {3} ({4})", integrationQueueItem.Project.Name, Name, queuePosition, integrationQueueItem.IntegrationRequest.Source,integrationQueueItem.IntegrationRequest.UserName)); } integrationQueueItem.IntegrationQueueNotifier.NotifyEnteringIntegrationQueue(); Insert(queuePosition.Value, integrationQueueItem); }