From 0c5bfb274ff783d70941af8f3817894e759db10d Mon Sep 17 00:00:00 2001 From: Rory& Date: Thu, 2 May 2024 07:22:22 +0200 Subject: Some work --- .gitignore | 1 + BugMine.DevTools.CLI/Worker.cs | 132 +++++++++++++++++------- BugMine.Sdk/BugMineClient.cs | 17 +-- BugMine.Sdk/BugMineProject.cs | 28 +++-- BugMine.Sdk/Events/State/BugMineRoomMetadata.cs | 2 +- BugMine.Web/Pages/Auth/LegacyLogin.razor | 1 + BugMine.Web/Pages/Projects/Index.razor | 10 +- BugMine.Web/Pages/Projects/ViewProject.razor | 6 ++ BugMine.sln | 10 ++ LibMatrix | 2 +- 10 files changed, 149 insertions(+), 60 deletions(-) diff --git a/.gitignore b/.gitignore index 1821c7e..51eecb3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ test-proxy.tsv homeservers.txt LoginPayload.txt LoginPayload.txt.old +BugMine.DevTools.CLI/auth.json diff --git a/BugMine.DevTools.CLI/Worker.cs b/BugMine.DevTools.CLI/Worker.cs index 8cd931e..900d742 100644 --- a/BugMine.DevTools.CLI/Worker.cs +++ b/BugMine.DevTools.CLI/Worker.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Text.Json; using ArcaneLibs.Extensions; using BugMine.Web.Classes; @@ -30,74 +31,90 @@ public class Worker(ILogger logger, HomeserverProviderService hsProvider while (!stoppingToken.IsCancellationRequested) { Console.WriteLine(""" 1) List all projects - 2) Create 500 projects + 2) Mass create projects 3) Destroy all projects 4) Get room count + 5) Summarize all projects + 6) Mass create regular rooms + + L) Logout + Q) Quit """); var input = Console.ReadKey(); Console.WriteLine(); switch (input.Key) { case ConsoleKey.D1: { - if (Client is null) { - _logger.LogError("No client available."); - break; - } - + var sw = Stopwatch.StartNew(); var projects = Client.GetProjects(); await foreach (var project in projects) { Console.WriteLine(project.ToJson(indent: false)); } + Console.WriteLine($"Queried in {sw.Elapsed}"); break; } case ConsoleKey.D2: { - if (Client is null) { - _logger.LogError("No client available."); - break; - } - await MassCreateProjects(); break; } case ConsoleKey.D3: { - if (Client is null) { - _logger.LogError("No client available."); - break; - } - await DestroyAllProjects(); break; } case ConsoleKey.D4: { - if (Client is null) { - _logger.LogError("No client available."); - break; + var sw = Stopwatch.StartNew(); + var rooms = await Client.Homeserver.GetJoinedRooms(); + Console.WriteLine(rooms.Count() + " rooms."); + var projectCount = 0; + await foreach (var room in Client.Homeserver.GetJoinedRoomsByType("gay.rory.bugmine.project").WithCancellation(stoppingToken)) { + projectCount++; } - var rooms = await Client.Homeserver.GetJoinedRooms(); - Console.WriteLine(rooms.Count()); + Console.WriteLine($"{projectCount} projects ({rooms.Count} rooms) queried in {sw.Elapsed}"); break; } + case ConsoleKey.D5: { + await SummarizeAllProjects(); + break; + } + case ConsoleKey.D6: { + var sw = Stopwatch.StartNew(); + await Task.WhenAll(Enumerable.Range(0,1000).Select(async _ => { + await Client.Homeserver.CreateRoom(new() { + Name = Guid.NewGuid().ToString()[..8] + }); + })); + Console.WriteLine($"Created 1000 rooms in {sw.Elapsed}"); + break; + } + case ConsoleKey.L: { + File.Delete("auth.json"); + await ExecuteAsync(stoppingToken); + return; + } + case ConsoleKey.Q: { + Environment.Exit(0); + return; + } } } } private async Task DestroyAllProjects() { - var ss = new SemaphoreSlim(4, 4); - await foreach (var proj in Client.Homeserver.GetJoinedRoomsByType(null!)) { - if (proj.RoomId == "!UktPWOzit8gmms5FQ6:conduit.matrixunittests.rory.gay") continue; + var ss = new SemaphoreSlim(48, 48); + await foreach (var proj in Client.Homeserver.GetJoinedRoomsByType("gay.rory.bugmine.project")) { Task.Run(async () => { // await ss.WaitAsync(); - await proj.SendStateEventAsync(RoomNameEventContent.EventId, new RoomNameEventContent() { - Name = "Disbanded BugMine project." - }); - await proj.SendStateEventAsync(RoomJoinRulesEventContent.EventId, new RoomJoinRulesEventContent() { - JoinRule = RoomJoinRulesEventContent.JoinRules.Private - }); - await proj.SendStateEventAsync(RoomCanonicalAliasEventContent.EventId, new RoomCanonicalAliasEventContent() { - Alias = null - }); + // await proj.SendStateEventAsync(RoomNameEventContent.EventId, new RoomNameEventContent() { + // Name = "Disbanded BugMine project." + // }); + // await proj.SendStateEventAsync(RoomJoinRulesEventContent.EventId, new RoomJoinRulesEventContent() { + // JoinRule = RoomJoinRulesEventContent.JoinRules.Private + // }); + // await proj.SendStateEventAsync(RoomCanonicalAliasEventContent.EventId, new RoomCanonicalAliasEventContent() { + // Alias = null + // }); await proj.LeaveAsync("Disbanded room."); // ss.Release(); }); @@ -106,18 +123,59 @@ public class Worker(ILogger logger, HomeserverProviderService hsProvider private async Task MassCreateProjects() { // var rooms = await Client.Homeserver.GetJoinedRooms(); - // List roomNames = (await Task.WhenAll(rooms.Select(x => x.GetNameAsync()))).Where(x => x != null).ToList(); + // List roomNames = (await Task.WhenAll(rooms.Select(x => x.GetNameAsync()))).Where(x => x != + var tasks = new List(); for (int i = 0; i < 500; i++) { - Task.Run(async () => { + tasks.Add(Task.Run(async () => { // var randomName = roomNames[Random.Shared.Next(roomNames.Count)]; var proj = await Client.CreateProject(new() { Name = /*randomName + */Guid.NewGuid().ToString()[..8] }); // await proj.CreateIssue(new() { - // Name = "meow" + // Name = "meow" // }); - }); + await CreateRandomIssues(proj, Random.Shared.Next(20)); + })); + // await Task.Delay(250); + } + + await Task.WhenAll(tasks); + } + + private async Task SummarizeProject(BugMineProject project) { + string result = $"Project: {project.Info.Name}, slug: {project.ProjectSlug}, metadata: {project.Metadata.ToJson(indent: false)}"; + await foreach (var issue in project.GetIssues()) { + // Console.WriteLine($" - {issue.Data.RawContent.ToJson(indent: false)}"); + result += $"\n - {issue.Data.RawContent.ToJson(indent: false)}"; + } + + return result; + } + + private async Task SummarizeAllProjects() { + var sw = Stopwatch.StartNew(); + var tasks = new List>(); + await foreach (var project in Client.GetProjects()) { + tasks.Add(SummarizeProject(project)); + } + + int projects = 0; + int issues = 0; + await foreach (var res in tasks.ToAsyncEnumerable()) { + Console.WriteLine(res + "\n"); + projects++; + issues += res.Count(x => x == '\n'); } + + Console.WriteLine($"Summarized {projects} projects with {issues} issues in {sw.Elapsed}"); + } + + private async Task CreateRandomIssues(BugMineProject project, int count) { + await Task.WhenAll(Enumerable.Range(0, count).Select(async i => { + await project.CreateIssue(new() { + Name = $"Issue {i} @ {DateTime.Now}" + }); + })); } } \ No newline at end of file diff --git a/BugMine.Sdk/BugMineClient.cs b/BugMine.Sdk/BugMineClient.cs index db47b85..21be614 100644 --- a/BugMine.Sdk/BugMineClient.cs +++ b/BugMine.Sdk/BugMineClient.cs @@ -11,10 +11,11 @@ namespace BugMine.Web.Classes; public class BugMineClient(AuthenticatedHomeserverGeneric homeserver) { public AuthenticatedHomeserverGeneric Homeserver { get; } = homeserver; - public async IAsyncEnumerable GetProjects() { + public async IAsyncEnumerable GetProjects(SemaphoreSlim? semaphore = null) { List> tasks = []; - await foreach (var room in homeserver.GetJoinedRoomsByType(BugMineProject.RoomType)) { - tasks.Add(room.AsBugMineProject()); + int count = 0; + await foreach (var room in homeserver.GetJoinedRoomsByType(BugMineProject.RoomType, 64)) { + tasks.Add(room.AsBugMineProject(semaphore)); } var results = tasks.ToAsyncEnumerable(); @@ -46,10 +47,14 @@ public class BugMineClient(AuthenticatedHomeserverGeneric homeserver) { ] }; - var response = await Homeserver.CreateRoom(crr); - // await response.SendStateEventAsync(ProjectInfo.EventId, request); + var newRoom = await Homeserver.CreateRoom(crr); + var timeline = await newRoom.GetMessagesAsync(); + + await newRoom.SendStateEventAsync(BugMineRoomMetadata.EventId, new BugMineRoomMetadata() { + RoomCreationEventId = timeline.Chunk.Single(m => m.Type == "m.room.create").EventId! + }); - return await response.AsBugMineProject(); + return await newRoom.AsBugMineProject(); } public async Task GetProject(string projectSlug) { diff --git a/BugMine.Sdk/BugMineProject.cs b/BugMine.Sdk/BugMineProject.cs index babb680..1f56659 100644 --- a/BugMine.Sdk/BugMineProject.cs +++ b/BugMine.Sdk/BugMineProject.cs @@ -1,6 +1,4 @@ -using System.Text.Json.Nodes; -using LibMatrix.EventTypes.Spec.State; -using LibMatrix.Homeservers; +using ArcaneLibs.Extensions; using LibMatrix.RoomTypes; namespace BugMine.Web.Classes; @@ -9,43 +7,51 @@ public class BugMineProject(GenericRoom room) { public const string RoomType = "gay.rory.bugmine.project"; public GenericRoom Room { get; } = room; public ProjectInfo Info { get; set; } + public BugMineRoomMetadata Metadata { get; set; } public string ProjectSlug { get; set; } public async Task InitializeAsync() { - Info = (await Room.GetStateAsync(ProjectInfo.EventId))!; + var infoTask = Room.GetStateAsync(ProjectInfo.EventId); + var metadataTask = Room.GetStateAsync(BugMineRoomMetadata.EventId)!; var alias = await room.GetCanonicalAliasAsync(); if (alias != null) ProjectSlug = alias.Alias?[1..] ?? room.RoomId; else ProjectSlug = room.RoomId; + Info = (await infoTask)!; + Metadata = (await metadataTask)!; return this; } public async Task CreateIssue(BugMineIssueData issue) { // add relation to room creation event issue.RelatesTo = new() { - EventId = await room.GetStateEventIdAsync(RoomCreateEventContent.EventId), + EventId = Metadata.RoomCreationEventId, RelationType = "gay.rory.bugmine.issue" }; var eventId = await Room.SendTimelineEventAsync(BugMineIssueData.EventId, issue); - // return new BugMineIssueAccessor(Room, await Room.GetEventAsync<>(eventId)); var evt = await room.GetEventAsync(eventId.EventId); - Console.WriteLine(evt); + Console.WriteLine(evt.ToJson(indent: false)); return new BugMineIssue(Room, evt); } public async IAsyncEnumerable GetIssues() { - var creationEventId = await room.GetStateEventIdAsync(RoomCreateEventContent.EventId); - await foreach (var evt in room.GetRelatedEventsAsync(creationEventId, "gay.rory.bugmine.issue", BugMineIssueData.EventId)) { + await foreach (var evt in room.GetRelatedEventsAsync(Metadata.RoomCreationEventId, "gay.rory.bugmine.issue", BugMineIssueData.EventId)) { yield return new BugMineIssue(Room, evt); } } } public static class ProjectRoomExtensions { - public static async Task AsBugMineProject(this GenericRoom room) { - return await new BugMineProject(room).InitializeAsync(); + public static async Task AsBugMineProject(this GenericRoom room, SemaphoreSlim? semaphore = null) { + try { + await (semaphore?.WaitAsync() ?? Task.CompletedTask); + return await new BugMineProject(room).InitializeAsync(); + } + finally { + semaphore?.Release(); + } } } \ No newline at end of file diff --git a/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs b/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs index a6686d3..734fd37 100644 --- a/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs +++ b/BugMine.Sdk/Events/State/BugMineRoomMetadata.cs @@ -7,5 +7,5 @@ public class BugMineRoomMetadata : EventContent { public const string EventId = "gay.rory.bugmine.room_metadata"; public string RoomCreationEventId { get; set; } - + } \ No newline at end of file diff --git a/BugMine.Web/Pages/Auth/LegacyLogin.razor b/BugMine.Web/Pages/Auth/LegacyLogin.razor index eec381a..bcfac61 100644 --- a/BugMine.Web/Pages/Auth/LegacyLogin.razor +++ b/BugMine.Web/Pages/Auth/LegacyLogin.razor @@ -48,6 +48,7 @@ await BugMineStorage.AddToken(result); await BugMineStorage.SetCurrentToken(result); + NavigationManager.NavigateTo("/", forceLoad: true); } catch (Exception e) { Console.WriteLine($"Failed to login to {record.Homeserver} as {record.Username}!"); diff --git a/BugMine.Web/Pages/Projects/Index.razor b/BugMine.Web/Pages/Projects/Index.razor index 47c2f4a..8f46d02 100644 --- a/BugMine.Web/Pages/Projects/Index.razor +++ b/BugMine.Web/Pages/Projects/Index.razor @@ -43,12 +43,14 @@ else { return; } StateHasChanged(); - - await foreach (var project in Client.GetProjects()) { + + int count = 0; + SemaphoreSlim semaphore = new(16, 16); + await foreach (var project in Client.GetProjects(semaphore)) { Projects ??= []; Projects.Add(project); - StateHasChanged(); - // await Task.Delay(100); + if(count++ <= 250 || count % 4 == 0) + StateHasChanged(); } Projects ??= []; diff --git a/BugMine.Web/Pages/Projects/ViewProject.razor b/BugMine.Web/Pages/Projects/ViewProject.razor index a778728..ec10d1c 100644 --- a/BugMine.Web/Pages/Projects/ViewProject.razor +++ b/BugMine.Web/Pages/Projects/ViewProject.razor @@ -1,6 +1,7 @@ @page "/Projects/{ProjectSlug}/" @using LibMatrix @using BugMine.Web.Classes.Exceptions +@using ArcaneLibs.Extensions @@ -29,6 +30,11 @@ else {

Loading issues, got @(Issues?.Count ?? 0) so far...

} @*

@Project.Description

*@ + @if (Issues != null) { + @foreach(var issue in Issues) { +
@issue.Data.RawContent.ToJson()
+ } + } } @code { diff --git a/BugMine.sln b/BugMine.sln index c6b4a4b..f6d49f3 100644 --- a/BugMine.sln +++ b/BugMine.sln @@ -18,6 +18,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugMine.Sdk", "BugMine.Sdk\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BugMine.DevTools.CLI", "BugMine.DevTools.CLI\BugMine.DevTools.CLI.csproj", "{E4E398A6-98CE-4B78-9E80-42A03765CE07}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E25BCB86-1123-481D-BA11-920B76006305}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.HomeserverEmulator", "LibMatrix\Tests\LibMatrix.HomeserverEmulator\LibMatrix.HomeserverEmulator.csproj", "{630BD644-B739-4876-B45C-085FF60C7269}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -48,11 +52,17 @@ Global {E4E398A6-98CE-4B78-9E80-42A03765CE07}.Debug|Any CPU.Build.0 = Debug|Any CPU {E4E398A6-98CE-4B78-9E80-42A03765CE07}.Release|Any CPU.ActiveCfg = Release|Any CPU {E4E398A6-98CE-4B78-9E80-42A03765CE07}.Release|Any CPU.Build.0 = Release|Any CPU + {630BD644-B739-4876-B45C-085FF60C7269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {630BD644-B739-4876-B45C-085FF60C7269}.Debug|Any CPU.Build.0 = Debug|Any CPU + {630BD644-B739-4876-B45C-085FF60C7269}.Release|Any CPU.ActiveCfg = Release|Any CPU + {630BD644-B739-4876-B45C-085FF60C7269}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {F4E241C3-0300-4B87-8707-BCBDEF1F0185} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33} {1CAA2B6D-0365-4C8B-96EE-26026514FEE2} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33} {B00E29F5-1ED8-40A0-A70D-DE9F23FC572F} = {B00C5CB6-6200-4B41-96BE-C6EAF1085A14} {2D6F31D7-3139-44EC-9D11-486282DD4ED1} = {B00C5CB6-6200-4B41-96BE-C6EAF1085A14} + {E25BCB86-1123-481D-BA11-920B76006305} = {8F4F6BEC-0C66-486B-A21A-1C35B2EDAD33} + {630BD644-B739-4876-B45C-085FF60C7269} = {E25BCB86-1123-481D-BA11-920B76006305} EndGlobalSection EndGlobal diff --git a/LibMatrix b/LibMatrix index 5ca0a45..508c694 160000 --- a/LibMatrix +++ b/LibMatrix @@ -1 +1 @@ -Subproject commit 5ca0a45606ad2ca7e1ca45a3b27be08e9640dd9d +Subproject commit 508c694c3d551cddb3b15c1b0d4787dae3c00530 -- cgit 1.4.1