Skip to content

Commit

Permalink
Minor bug fix: better handling of non-existing image
Browse files Browse the repository at this point in the history
  • Loading branch information
VoltanFr committed Nov 22, 2024
1 parent 646eac3 commit dca22b3
Show file tree
Hide file tree
Showing 14 changed files with 124 additions and 19 deletions.
3 changes: 3 additions & 0 deletions .globalconfig
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,6 @@ dotnet_diagnostic.CS8019.severity = error

# I allow constant array arguments
dotnet_diagnostic.CA1861.severity = none

# Sometimes a good old if is more readable
dotnet_diagnostic.IDE0046.severity = none
4 changes: 4 additions & 0 deletions MemCheck.Application/Images/GetImageFromName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ protected override async Task<ResultWithMetrologyProperties<Result>> DoRunAsync(
Request.ImageSize.Big => (await DbContext.Images.AsNoTracking().Select(img => new { img.Name, img.BigBlob }).SingleAsync(img => img.Name == request.ImageName)).BigBlob,
_ => throw new NotImplementedException(request.Size.ToString()),
};

if (result == null)
throw new ImageNotFoundException(request.ImageName);

return new ResultWithMetrologyProperties<Result>(new Result(result.ToImmutableArray()), ("ImageName", request.ImageName), ("RequestedSize", request.Size.ToString()), IntMetric("ByteCount", result.Length));
}
#region Request class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public static class MemCheckSupportedCultures
public static CultureInfo French { get; } = new("fr-FR");
public static ImmutableArray<CultureInfo> All => new[] { English, French }.ToImmutableArray();

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "More complicated")]
public static string? IdFromCulture(CultureInfo c)
{
if (English.Equals(c))
Expand Down
2 changes: 1 addition & 1 deletion MemCheck.Application/MemCheck.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Library</OutputType>
<VersionPrefix>0.59.1</VersionPrefix>
<VersionPrefix>0.60.0</VersionPrefix>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public static async Task CheckCardsArePrivateAsync(MemCheckDbContext dbContext,
throw new RequestInputException("At least one non-private card");
}

[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "Too complicated")]
public static bool CardIsPrivateToSingleUser(Guid userId, IEnumerable<Guid> usersWithView)
{
if (QueryValidationHelper.IsReservedGuid(userId))
Expand Down
1 change: 0 additions & 1 deletion MemCheck.Basics/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ namespace MemCheck.Basics;

public static class StringExtensions
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0046:Convert to conditional expression", Justification = "Conditional is more complicated")]
public static string Truncate(this string str, int maxLength, bool addElipsis = true)
{
if (string.IsNullOrEmpty(str))
Expand Down
4 changes: 2 additions & 2 deletions MemCheck.CommandLineDbClient/Engine.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using MemCheck.CommandLineDbClient.PerfMeasurements.Cards;
using MemCheck.CommandLineDbClient.PerfMeasurements.Images;
using MemCheck.Database;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -23,7 +23,7 @@ internal sealed class Engine : IHostedService
[System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance", Justification = "Often changes")]
private ICmdLinePlugin GetPlugin()
{
return new GetCardForEditPerfMeasurements(serviceProvider);
return new GetImageFromNamePerfMeasurements(serviceProvider);
}
#endregion
public Engine(IServiceProvider serviceProvider)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using MemCheck.Application.Images;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace MemCheck.CommandLineDbClient.PerfMeasurements.Images;

internal sealed class GetImageFromNamePerfMeasurements : AbstractPerfMeasurements<GetImageFromNamePerfMeasurements.TestDefinition>
{
internal sealed record TestDefinition : PerfTestDefinition
{
public TestDefinition(string description, int byteCount, GetImageFromName.Request request) : base(description)
{
Request = request;
ByteCount = byteCount;
}

public int ByteCount { get; set; }

public GetImageFromName.Request Request { get; }

public override void LogDetailsOnEnd(ILogger logger)
{
logger.LogInformation($"\tImage bytes: {ByteCount}");
}
}
public GetImageFromNamePerfMeasurements(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
protected override async Task<IEnumerable<TestDefinition>> CreateTestDefinitionsAsync()
{
var imageNames = CallContext.DbContext.Images.Select(img => img.Name);
foreach (var imageName in imageNames)
Console.WriteLine(imageName);

await Task.CompletedTask;
return new[] {
new TestDefinition("Small image", int.MinValue, new GetImageFromName.Request("Vocabulaire anglais bateau", GetImageFromName.Request.ImageSize.Small)),
new TestDefinition("Big image", int.MinValue,new GetImageFromName.Request("Voiliers au port", GetImageFromName.Request.ImageSize.Big))
};
}
protected override int IterationCount => 1000;
public override void DescribeForOpportunityToCancel()
{
Logger.LogInformation("Will measure perf of getting an image from its name");
}
protected override async Task RunTestAsync(TestDefinition test)
{
var search = new GetImageFromName(CallContext);
var chrono = Stopwatch.StartNew();
var result = await search.RunAsync(test.Request);
chrono.Stop();

if (test.AnomalyCount == -1) // On first run, we keep the values, and we don't save the chrono, since we consider this run as a pre-heat
{
test.AnomalyCount = 0;
test.ByteCount = result.ImageBytes.Length;
}
else
{
test.RunSpentSeconds.Add(chrono.Elapsed.TotalSeconds);
if (result.ImageBytes.Length != test.ByteCount)
{
Logger.LogError($"Unexpected byte count (not equal to first run)");
test.AnomalyCount++;
}
}
}
}
14 changes: 11 additions & 3 deletions MemCheck.WebUI/Controllers/LearnController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,17 @@ static GetImageFromName.Request.ImageSize AppSizeFromWebParam(int size)
}

CheckBodyParameter(request);
var blob = await new GetImageFromName(callContext).RunAsync(new GetImageFromName.Request(request.ImageName, AppSizeFromWebParam(request.Size)));
var content = new MemoryStream(blob.ImageBytes.ToArray());
return base.File(content, "image/jpeg", "noname.jpg");

try
{
var blob = await new GetImageFromName(callContext).RunAsync(new GetImageFromName.Request(request.ImageName, AppSizeFromWebParam(request.Size)));
var content = new MemoryStream(blob.ImageBytes.ToArray());
return base.File(content, "image/jpeg", "noname.jpg");
}
catch (ImageNotFoundException)
{
return NotFound();
}
}
public sealed class GetImageByNameRequest
{
Expand Down
26 changes: 20 additions & 6 deletions MemCheck.WebUI/Controllers/MediaController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,16 @@ public GetImageMetadataForEditViewModel(string imageName, string source, string
[HttpPost("GetImageMetadataFromName")] // No authorization: when running a demo without user, this is needed
public async Task<IActionResult> GetImageMetadataFromName([FromBody] GetImageMetadataFromNameRequest request)
{
var appRequest = new GetImageInfoFromName(callContext);
var result = await appRequest.RunAsync(new GetImageInfoFromName.Request(request.ImageName));
return Ok(new GetImageMetadataFromNameViewModel(result.Id, result.Description, result.Source, result.InitialUploadUtcDate, result.InitialVersionCreator, result.CurrentVersionUtcDate, result.CurrentVersionDescription, result.CardCount, result.OriginalImageContentType, result.OriginalImageSize, result.SmallSize, result.MediumSize, result.BigSize));
try
{
var appRequest = new GetImageInfoFromName(callContext);
var result = await appRequest.RunAsync(new GetImageInfoFromName.Request(request.ImageName));
return Ok(new GetImageMetadataFromNameViewModel(result.Id, result.Description, result.Source, result.InitialUploadUtcDate, result.InitialVersionCreator, result.CurrentVersionUtcDate, result.CurrentVersionDescription, result.CardCount, result.OriginalImageContentType, result.OriginalImageSize, result.SmallSize, result.MediumSize, result.BigSize));
}
catch (ImageNotFoundException)
{
return NotFound();
}
}
public sealed class GetImageMetadataFromNameRequest
{
Expand Down Expand Up @@ -174,9 +181,16 @@ public GetImageMetadataFromNameViewModel(Guid imageId, string description, strin
[HttpGet("GetImageMetadataFromId/{imageId}"), Authorize]
public async Task<IActionResult> GetImageMetadataFromId(Guid imageId)
{
var appRequest = new GetImageInfoFromId(callContext);
var result = await appRequest.RunAsync(new GetImageInfoFromId.Request(imageId));
return Ok(new GetImageMetadataFromIdViewModel(imageId, result.ImageName, result.Description, result.Source, result.InitialUploadUtcDate, result.CurrentVersionCreatorName, result.LastChangeUtcDate, result.CurrentVersionDescription, result.CardCount, result.OriginalImageContentType, result.OriginalImageSize, result.SmallSize, result.MediumSize, result.BigSize));
try
{
var appRequest = new GetImageInfoFromId(callContext);
var result = await appRequest.RunAsync(new GetImageInfoFromId.Request(imageId));
return Ok(new GetImageMetadataFromIdViewModel(imageId, result.ImageName, result.Description, result.Source, result.InitialUploadUtcDate, result.CurrentVersionCreatorName, result.LastChangeUtcDate, result.CurrentVersionDescription, result.CardCount, result.OriginalImageContentType, result.OriginalImageSize, result.SmallSize, result.MediumSize, result.BigSize));
}
catch (ImageNotFoundException)
{
return NotFound();
}
}
public sealed class GetImageMetadataFromIdRequest
{
Expand Down
2 changes: 1 addition & 1 deletion MemCheck.WebUI/MemCheck.WebUI.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<VersionPrefix>0.186.17</VersionPrefix>
<VersionPrefix>0.187.0</VersionPrefix>
</PropertyGroup>

<ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion MemCheck.WebUI/Resources/Controllers/MediaController.en.resx
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,7 @@
<data name="UnknownImage" xml:space="preserve">
<value>Unknown image</value>
</data>
</root>
<data name="ImageNotFound" xml:space="preserve">
<value>Image not found</value>
</data>
</root>
5 changes: 4 additions & 1 deletion MemCheck.WebUI/Resources/Controllers/MediaController.fr.resx
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,7 @@
<data name="UnknownImage" xml:space="preserve">
<value>Image non trouvée</value>
</data>
</root>
<data name="ImageNotFound" xml:space="preserve">
<value>Image inexistante</value>
</data>
</root>
3 changes: 2 additions & 1 deletion MemCheck.WebUI/wwwroot/js/Learn/Learn.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ const learnApp = Vue.createApp({
if (!this.currentCard)
this.getCard();
})
.catch(() => {
.catch((error) => {
tellAxiosError(error);
sleep(1000).then(() => {
this.currentImageDetailsLoadingPromise = null;
});
Expand Down

0 comments on commit dca22b3

Please sign in to comment.