/// <summary> /// Process a timer event /// </summary> async private void onTimer(object sender, System.Timers.ElapsedEventArgs e) { string hostname = Workflow.State.HostName; List <Project> enabledProjects = Workflow.GetProjectsToUpdate(); IWorkflowDetails oldDetails = Cache.Details.Clone(); try { await Cache.UpdateAsync(); } catch (OperatorException ex) { ExceptionHandlers.Handle(ex, "Auto-update failed"); return; } MergeRequestUpdates updates = WorkflowDetailsChecker.CheckForUpdates(hostname, enabledProjects, oldDetails, Cache.Details); ProjectWatcher.ProcessUpdates(updates, Workflow.State.HostName, Cache.Details); Trace.TraceInformation( String.Format("[UpdateManager] Merge Request Updates: New {0}, Updated {1}, Closed {2}", updates.NewMergeRequests.Count, updates.UpdatedMergeRequests.Count, updates.ClosedMergeRequests.Count)); OnUpdate?.Invoke(updates); }
/// <summary> /// Process a timer event /// </summary> internal MergeRequestUpdates CheckForUpdates(string hostname, List <Project> enabledProjects, IWorkflowDetails oldDetails, IWorkflowDetails newDetails) { TwoListDifference <MergeRequest> diff = getMergeRequestDiff(hostname, enabledProjects, oldDetails, newDetails); return(getMergeRequestUpdates(diff, oldDetails, newDetails)); }
/// <summary> /// Convert passed updates to ProjectUpdates and notify subscribers /// </summary> internal void ProcessUpdates(MergeRequestUpdates updates, string hostname, IWorkflowDetails details) { List <ProjectUpdate> projectUpdates = new List <ProjectUpdate>(); projectUpdates.AddRange(getProjectUpdates(updates.NewMergeRequests, hostname, details)); projectUpdates.AddRange(getProjectUpdates(updates.UpdatedMergeRequests, hostname, details)); if (projectUpdates.Count > 0) { foreach (ProjectUpdate projectUpdate in projectUpdates) { Trace.TraceInformation( String.Format("[ProjectWatcher] Updating project: Host {0}, Name {1}, TimeStamp {2}", projectUpdate.HostName, projectUpdate.ProjectName, projectUpdate.Timestamp.ToLocalTime().ToString())); } OnProjectUpdate?.Invoke(projectUpdates); } }
/// <summary> /// Convert a list of Project Id to list of Project names /// </summary> private List <ProjectUpdate> getProjectUpdates(List <MergeRequest> mergeRequests, string hostname, IWorkflowDetails details) { List <ProjectUpdate> projectUpdates = new List <ProjectUpdate>(); // Check all the updated merge request to figure out the latest change among them DateTime updateTimestamp = DateTime.MinValue; foreach (MergeRequest mergeRequest in mergeRequests) { ProjectKey key = new ProjectKey { HostName = hostname, ProjectId = mergeRequest.Project_Id }; string projectName = details.GetProjectName(key); // Excluding duplicates for (int iUpdate = projectUpdates.Count - 1; iUpdate >= 0; --iUpdate) { if (projectUpdates[iUpdate].ProjectName == projectName) { projectUpdates.RemoveAt(iUpdate); } } updateTimestamp = details.GetLatestChangeTimestamp(mergeRequest.Id) > updateTimestamp? details.GetLatestChangeTimestamp(mergeRequest.Id) : updateTimestamp; projectUpdates.Add( new ProjectUpdate { HostName = hostname, ProjectName = projectName, Timestamp = updateTimestamp }); } return(projectUpdates); }
/// <summary> /// Convert a difference between two states into a list of merge request updates splitted in new/updated/closed /// </summary> private MergeRequestUpdates getMergeRequestUpdates( TwoListDifference <MergeRequest> diff, IWorkflowDetails oldDetails, IWorkflowDetails newDetails) { MergeRequestUpdates updates = new MergeRequestUpdates { NewMergeRequests = diff.SecondOnly, UpdatedMergeRequests = new List <MergeRequest>(), // will be filled in below ClosedMergeRequests = diff.FirstOnly }; foreach (MergeRequest mergeRequest in diff.Common) { DateTime previouslyCachedChangeTimestamp = oldDetails.GetLatestChangeTimestamp(mergeRequest.Id); DateTime newCachedChangeTimestamp = newDetails.GetLatestChangeTimestamp(mergeRequest.Id); if (newCachedChangeTimestamp > previouslyCachedChangeTimestamp) { updates.UpdatedMergeRequests.Add(mergeRequest); } } return(updates); }
internal LocalProjectChecker(int mergeRequestId, IWorkflowDetails details) { MergeRequestId = mergeRequestId; Details = details; }
/// <summary> /// Calculate difference between two WorkflowDetails objects /// </summary> private TwoListDifference <MergeRequest> getMergeRequestDiff(string hostname, List <Project> enabledProjects, IWorkflowDetails oldDetails, IWorkflowDetails newDetails) { TwoListDifference <MergeRequest> diff = new TwoListDifference <MergeRequest> { FirstOnly = new List <MergeRequest>(), SecondOnly = new List <MergeRequest>(), Common = new List <MergeRequest>() }; foreach (var project in enabledProjects) { ProjectKey key = new ProjectKey { HostName = hostname, ProjectId = project.Id }; List <MergeRequest> previouslyCachedMergeRequests = oldDetails.GetMergeRequests(key); List <MergeRequest> newCachedMergeRequests = newDetails.GetMergeRequests(key); diff.FirstOnly.AddRange(previouslyCachedMergeRequests.Except(newCachedMergeRequests).ToList()); diff.SecondOnly.AddRange(newCachedMergeRequests.Except(previouslyCachedMergeRequests).ToList()); diff.Common.AddRange(previouslyCachedMergeRequests.Intersect(newCachedMergeRequests).ToList()); } return(diff); }