2 Commits

Author SHA1 Message Date
a4d52349c7 added multithreaded api calling on about page
All checks were successful
Portfolio CI/CD / build (push) Successful in 1m5s
Portfolio CI/CD / test (push) Successful in 1m24s
Portfolio CI/CD / publish (push) Successful in 1m16s
2026-02-22 12:25:54 +01:00
aac2f5180b added multithreaded api calling on homepage
All checks were successful
Portfolio CI/CD / build (push) Successful in 1m8s
Portfolio CI/CD / test (push) Successful in 1m51s
Portfolio CI/CD / publish (push) Has been skipped
2026-02-22 12:22:20 +01:00
12 changed files with 67 additions and 10 deletions

View File

@@ -12,5 +12,11 @@ public class ProjectController(IProjectRepository repository) : ControllerBase {
var projects = await repository.GetProjects(ct); var projects = await repository.GetProjects(ct);
return Ok(projects); return Ok(projects);
} }
[HttpGet("featured")]
public async Task<IActionResult> GetFeaturedProjects(CancellationToken ct) {
var projects = await repository.GetFeaturedProjects(ct);
return Ok(projects);
}
} }

View File

@@ -12,5 +12,11 @@ public class TechnologyController(ITechnologyRepository repository) : Controller
var technologies = await repository.GetTechnologies(ct); var technologies = await repository.GetTechnologies(ct);
return Ok(technologies); return Ok(technologies);
} }
[HttpGet("featured")]
public async Task<IActionResult> GetFeaturedTechnologies(CancellationToken ct) {
var technologies = await repository.GetFeaturedTechnologies(ct);
return Ok(technologies);
}
} }

View File

@@ -10,7 +10,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="13.0.2" /> <PackageReference Include="Aspire.Npgsql.EntityFrameworkCore.PostgreSQL" Version="13.0.2" />
<PackageReference Include="Aspire.StackExchange.Redis.OutputCaching" Version="13.0.2" /> <PackageReference Include="Aspire.StackExchange.Redis.OutputCaching" Version="13.0.2" />
<PackageReference Include="HopFrame.Web" Version="3.2.0" /> <PackageReference Include="HopFrame.Web" Version="3.3.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.11" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.11" />
</ItemGroup> </ItemGroup>

View File

@@ -60,6 +60,8 @@ builder.Services.AddHopFrame(options => {
.IsTextArea(true); .IsTextArea(true);
}); });
}); });
options.AddExporters();
}); });
var app = builder.Build(); var app = builder.Build();

View File

@@ -12,5 +12,13 @@ internal sealed class ProjectRepository(DatabaseContext context) : IProjectRepos
.OrderByDescending(p => p.OrderIndex) .OrderByDescending(p => p.OrderIndex)
.ToArrayAsync(ct); .ToArrayAsync(ct);
} }
public async Task<IEnumerable<Project>> GetFeaturedProjects(CancellationToken ct) {
return await context.Projects
.Include(p => p.Languages)
.Where(p => p.Featured)
.OrderByDescending(p => p.OrderIndex)
.ToArrayAsync(ct);
}
} }

View File

@@ -9,5 +9,11 @@ internal sealed class TechnologyRepository(DatabaseContext context) : ITechnolog
public async Task<IEnumerable<Technology>> GetTechnologies(CancellationToken ct) { public async Task<IEnumerable<Technology>> GetTechnologies(CancellationToken ct) {
return await context.Technologies.ToArrayAsync(ct); return await context.Technologies.ToArrayAsync(ct);
} }
public async Task<IEnumerable<Technology>> GetFeaturedTechnologies(CancellationToken ct) {
return await context.Technologies
.Where(t => t.Featured)
.ToArrayAsync(ct);
}
} }

View File

@@ -6,4 +6,6 @@ public interface IProjectRepository {
Task<IEnumerable<Project>> GetProjects(CancellationToken ct); Task<IEnumerable<Project>> GetProjects(CancellationToken ct);
Task<IEnumerable<Project>> GetFeaturedProjects(CancellationToken ct);
} }

View File

@@ -6,4 +6,6 @@ public interface ITechnologyRepository {
Task<IEnumerable<Technology>> GetTechnologies(CancellationToken ct); Task<IEnumerable<Technology>> GetTechnologies(CancellationToken ct);
Task<IEnumerable<Technology>> GetFeaturedTechnologies(CancellationToken ct);
} }

View File

@@ -53,9 +53,15 @@
}; };
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync() {
_about = await AboutRepository.GetAbout(TokenSource.Token); var aboutTask = AboutRepository.GetAbout(TokenSource.Token);
_experience = await TimelineRepository.GetTimeline(TimelineEntryType.Experience, TokenSource.Token); var experienceTask = TimelineRepository.GetTimeline(TimelineEntryType.Experience, TokenSource.Token);
_carrier = await TimelineRepository.GetTimeline(TimelineEntryType.Carrier, TokenSource.Token); var carrierTask = TimelineRepository.GetTimeline(TimelineEntryType.Carrier, TokenSource.Token);
await Task.WhenAll(aboutTask, experienceTask, carrierTask);
_about = aboutTask.Result;
_experience = experienceTask.Result;
_carrier = carrierTask.Result;
} }
} }

View File

@@ -82,7 +82,6 @@
if (displayElement.innerText !== jobs.display) if (displayElement.innerText !== jobs.display)
displayElement.innerText = jobs.display; displayElement.innerText = jobs.display;
}, 50) }, 50)
</script> </script>
@inherits CancellableComponent @inherits CancellableComponent
@@ -98,13 +97,15 @@
private IEnumerable<TimelineEntry> _timeline = []; private IEnumerable<TimelineEntry> _timeline = [];
protected override async Task OnInitializedAsync() { protected override async Task OnInitializedAsync() {
var projects = await ProjectRepository.GetProjects(TokenSource.Token); var projectsTask = ProjectRepository.GetFeaturedProjects(TokenSource.Token);
_projects = projects.Where(p => p.Featured); var technologiesTask = TechnologyRepository.GetFeaturedTechnologies(TokenSource.Token);
var timelineTask = TimelineRepository.GetFeaturedTimeline(TokenSource.Token);
var technologies = await TechnologyRepository.GetTechnologies(TokenSource.Token); await Task.WhenAll(projectsTask, technologiesTask, timelineTask);
_technologies = technologies.Where(t => t.Featured);
_timeline = await TimelineRepository.GetFeaturedTimeline(TokenSource.Token); _projects = projectsTask.Result;
_technologies = technologiesTask.Result;
_timeline = timelineTask.Result;
} }
} }

View File

@@ -12,4 +12,13 @@ internal sealed class ProjectRepository(IHttpClientFactory factory) : IProjectRe
var data = await response.Content.ReadFromJsonAsync<IEnumerable<Project>>(ct); var data = await response.Content.ReadFromJsonAsync<IEnumerable<Project>>(ct);
return data?.OrderByDescending(p => p.OrderIndex) ?? Enumerable.Empty<Project>(); return data?.OrderByDescending(p => p.OrderIndex) ?? Enumerable.Empty<Project>();
} }
public async Task<IEnumerable<Project>> GetFeaturedProjects(CancellationToken ct) {
var client = factory.CreateClient("api");
var response = await client.GetAsync("api/projects/featured", ct);
if (!response.IsSuccessStatusCode) return [];
var data = await response.Content.ReadFromJsonAsync<IEnumerable<Project>>(ct);
return data?.OrderByDescending(p => p.OrderIndex) ?? Enumerable.Empty<Project>();
}
} }

View File

@@ -12,4 +12,13 @@ internal sealed class TechnologyRepository(IHttpClientFactory factory) : ITechno
var data = await response.Content.ReadFromJsonAsync<IEnumerable<Technology>>(ct); var data = await response.Content.ReadFromJsonAsync<IEnumerable<Technology>>(ct);
return data ?? []; return data ?? [];
} }
public async Task<IEnumerable<Technology>> GetFeaturedTechnologies(CancellationToken ct) {
var client = factory.CreateClient("api");
var response = await client.GetAsync("api/technologies/featured", ct);
if (!response.IsSuccessStatusCode) return [];
var data = await response.Content.ReadFromJsonAsync<IEnumerable<Technology>>(ct);
return data ?? [];
}
} }