Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9fd3bb7fa5 | |||
| 67cdfb0c21 | |||
| ddc7206a73 |
@@ -1,6 +1,7 @@
|
|||||||
using Blueberry.Redmine.Dto;
|
using Blueberry.Redmine.Dto;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -118,11 +119,14 @@ namespace Blueberry.Redmine
|
|||||||
private async Task<List<TReturn>> SendRequestWithPagingAsync<TResponse, TReturn>(HttpMethod method, string endpoint, int limit, Func<TResponse, List<TReturn>> itemParser,
|
private async Task<List<TReturn>> SendRequestWithPagingAsync<TResponse, TReturn>(HttpMethod method, string endpoint, int limit, Func<TResponse, List<TReturn>> itemParser,
|
||||||
IProgress<(int current, int total)>? progress = null, object? payload = null, CancellationToken? token = null) where TResponse : IResponseList
|
IProgress<(int current, int total)>? progress = null, object? payload = null, CancellationToken? token = null) where TResponse : IResponseList
|
||||||
{
|
{
|
||||||
|
var sw = new Stopwatch();
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
|
|
||||||
List<TReturn> returnList = [];
|
List<TReturn> returnList = [];
|
||||||
|
|
||||||
_logger.LogDebug("Starting paged request to {Endpoint} with limit {Limit}", endpoint, limit);
|
_logger.LogDebug("Starting paged request to {Endpoint} with limit {Limit}", endpoint.Split('?')[0], limit);
|
||||||
|
|
||||||
var path = "";
|
var path = "";
|
||||||
if (endpoint.Contains('?'))
|
if (endpoint.Contains('?'))
|
||||||
@@ -131,7 +135,7 @@ namespace Blueberry.Redmine
|
|||||||
path = $"{endpoint}?limit={limit}&offset={offset}";
|
path = $"{endpoint}?limit={limit}&offset={offset}";
|
||||||
|
|
||||||
var responseList = await SendRequestAsync<TResponse>(HttpMethod.Get, path, token: token)
|
var responseList = await SendRequestAsync<TResponse>(HttpMethod.Get, path, token: token)
|
||||||
?? throw new NullReferenceException();
|
?? throw new NullReferenceException();
|
||||||
|
|
||||||
var total = responseList.TotalCount;
|
var total = responseList.TotalCount;
|
||||||
|
|
||||||
@@ -140,16 +144,20 @@ namespace Blueberry.Redmine
|
|||||||
offset += limit;
|
offset += limit;
|
||||||
|
|
||||||
if (offset >= responseList.TotalCount)
|
if (offset >= responseList.TotalCount)
|
||||||
|
{
|
||||||
|
_logger.LogDebug(" + Single request retrieved all {TotalItems} items", returnList.Count);
|
||||||
return returnList;
|
return returnList;
|
||||||
|
}
|
||||||
|
|
||||||
var remain = total - offset;
|
var remain = total - offset;
|
||||||
|
|
||||||
var tasks = new Task[(int)Math.Ceiling((double)remain / limit)];
|
var tasks = new Task[(int)Math.Ceiling((double)remain / limit)];
|
||||||
|
|
||||||
_logger.LogDebug("Spawning {TaskCount} tasks for remaining {Remaining} items out of {Total}", tasks.Length, remain, total);
|
|
||||||
|
|
||||||
List<(int id, IEnumerable<TReturn> items)> responses = [];
|
List<(int id, IEnumerable<TReturn> items)> responses = [];
|
||||||
|
|
||||||
|
var preparationTime = sw.ElapsedMilliseconds;
|
||||||
|
sw.Restart();
|
||||||
|
|
||||||
for (int i = 0; i < tasks.Length; i++)
|
for (int i = 0; i < tasks.Length; i++)
|
||||||
{
|
{
|
||||||
var id = i;
|
var id = i;
|
||||||
@@ -178,25 +186,32 @@ namespace Blueberry.Redmine
|
|||||||
progress.Report((current, tasks.Length));
|
progress.Report((current, tasks.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
var completed = tasks.Count(t => t.IsCompleted);
|
|
||||||
_logger.LogDebug("{Completed}/{Total} tasks completed", completed, tasks.Length);
|
|
||||||
await Task.Delay(250);
|
await Task.Delay(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
await Task.Delay(100);
|
await Task.Delay(50);
|
||||||
|
var executionTime = sw.ElapsedMilliseconds;
|
||||||
var notCompleted = tasks.Where(t => !t.IsCompletedSuccessfully).ToList();
|
sw.Restart();
|
||||||
_logger.LogDebug("{NotCompleted} tasks did not complete successfully", notCompleted.Count);
|
|
||||||
|
|
||||||
_logger.LogDebug("All tasks completed, aggregating {total} results from {count} responses", responses.Select(x=>x.items).Count(), responses.Count);
|
|
||||||
|
|
||||||
foreach (var resp in responses.OrderBy(x => x.id))
|
foreach (var resp in responses.OrderBy(x => x.id))
|
||||||
{
|
{
|
||||||
returnList.AddRange(resp.items);
|
returnList.AddRange(resp.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("Aggregated total of {TotalItems} items", returnList.Count);
|
_logger.LogDebug(" + Aggregated total of {TotalItems} items from {Count} responses", returnList.Count, responses.Count);
|
||||||
|
|
||||||
|
var aggregationTime = sw.ElapsedMilliseconds;
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
// log times
|
||||||
|
_logger.LogDebug(" + Paging completed in:\n Preparation: {Preparation}ms\n Execution: {Execution}ms\n Aggregation: {Aggregation}ms\n Total: {Total}ms"
|
||||||
|
, preparationTime, executionTime, aggregationTime, preparationTime + executionTime + aggregationTime);
|
||||||
|
|
||||||
|
// log avarege time per task and per item, round them to whole ms
|
||||||
|
_logger.LogDebug(" + Average time per task: {AvgTask}ms, Average time per item: {AvgItem}ms",
|
||||||
|
Math.Round((double)(preparationTime + executionTime) / tasks.Length + 1),
|
||||||
|
Math.Round((double)(executionTime) / returnList.Count));
|
||||||
|
|
||||||
return returnList;
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Blueberry.Redmine.Dto;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Wpf.Ui.Controls;
|
using Wpf.Ui.Controls;
|
||||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
@@ -120,6 +121,10 @@ namespace Blueberry
|
|||||||
var firstDate = userCalendar.SelectedDates.First();
|
var firstDate = userCalendar.SelectedDates.First();
|
||||||
var lastDate = userCalendar.SelectedDates.Last();
|
var lastDate = userCalendar.SelectedDates.Last();
|
||||||
|
|
||||||
|
var newTicketTask = _manager.GetIssuesAsync(user.Id, createdFrom: selectedDates.First(), createdTo: selectedDates.Last());
|
||||||
|
var closedTicketTask = _manager.GetIssuesAsync(user.Id, isOpen: false, updatedFrom: selectedDates.First(), updatedTo: selectedDates.Last());
|
||||||
|
var currentTicketTask = _manager.GetUserOpenIssuesAsync(user.Id);
|
||||||
|
|
||||||
var h = await _manager.GetTimeForUserAsync(user.Id, firstDate, lastDate);
|
var h = await _manager.GetTimeForUserAsync(user.Id, firstDate, lastDate);
|
||||||
|
|
||||||
var list = new List<string>();
|
var list = new List<string>();
|
||||||
@@ -178,9 +183,11 @@ namespace Blueberry
|
|||||||
foreach (var item in orderedHours)
|
foreach (var item in orderedHours)
|
||||||
Hours.Add(item);
|
Hours.Add(item);
|
||||||
|
|
||||||
var newTickets = await _manager.GetIssuesAsync(user.Id, createdFrom: selectedDates.First(), createdTo: selectedDates.Last());
|
await Task.WhenAll(newTicketTask, closedTicketTask, currentTicketTask);
|
||||||
var closedTickets = await _manager.GetIssuesAsync(user.Id, isOpen: false, updatedFrom: selectedDates.First(), updatedTo: selectedDates.Last());
|
|
||||||
var currentTickets = await _manager.GetUserOpenIssuesAsync(user.Id);
|
var newTickets = newTicketTask.Result;
|
||||||
|
var closedTickets = closedTicketTask.Result;
|
||||||
|
var currentTickets = currentTicketTask.Result;
|
||||||
|
|
||||||
var total = hours.Sum(x => double.Parse(x.Hours));
|
var total = hours.Sum(x => double.Parse(x.Hours));
|
||||||
totalHoursTextBlock.Text = total.ToString();
|
totalHoursTextBlock.Text = total.ToString();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Blueberry
|
|||||||
public static class UpdateManager
|
public static class UpdateManager
|
||||||
{
|
{
|
||||||
private const string releaseUrl = "https://git.technopunk.space/api/v1/repos/tomi/Blueberry/releases/latest";
|
private const string releaseUrl = "https://git.technopunk.space/api/v1/repos/tomi/Blueberry/releases/latest";
|
||||||
public const string CurrentVersion = "0.2.5";
|
public const string CurrentVersion = "0.2.7";
|
||||||
private static readonly string appDir = AppDomain.CurrentDomain.BaseDirectory;
|
private static readonly string appDir = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
private static readonly string zipPath = Path.Combine(appDir, "blueberry_update.zip");
|
private static readonly string zipPath = Path.Combine(appDir, "blueberry_update.zip");
|
||||||
private static readonly HttpClient client = new();
|
private static readonly HttpClient client = new();
|
||||||
|
|||||||
Reference in New Issue
Block a user