Skip to content

Commit

Permalink
WIP - fixing nullability annotations and warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
lilith committed Jan 26, 2024
1 parent 9669e04 commit e51f9ec
Show file tree
Hide file tree
Showing 35 changed files with 561 additions and 562 deletions.
1 change: 1 addition & 0 deletions Imageflow.Server.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=HSTS/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=idct/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=ignoreicc/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=imagecache/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Imageflow/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Imazen/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=jfif/@EntryIndexedValue">True</s:Boolean>
Expand Down
2 changes: 1 addition & 1 deletion src/Imageflow.Server/ImageflowMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public async Task Invoke(HttpContext context)

if (await imageServer.TryHandleRequestAsync(requestAdapter, responseAdapter, context, context.RequestAborted))
{
options.Licensing.FireHeartbeat();
options.Licensing?.FireHeartbeat();
return; // We handled it
}
await next.Invoke(context);
Expand Down
2 changes: 1 addition & 1 deletion src/Imageflow.Server/Internal/ImageJobInstrumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public ImageJobInstrumentation(BuildJobResult jobResult)
public long TotalTicks { get; }
public long DecodeTicks { get; }
public long EncodeTicks { get; }
public string SourceFileExtension { get; }
public string? SourceFileExtension { get; }
public string? ImageDomain { get; set; }
public string? PageDomain { get; set; }
public IEnumerable<string>? FinalCommandKeys { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion src/Imageflow.Server/Internal/Licensing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public IEnumerable<KeyValuePair<string, string>> GetDomainMappings()
return Enumerable.Empty<KeyValuePair<string, string>>();
}

public IEnumerable<IEnumerable<string>> GetFeaturesUsed()
public IReadOnlyCollection<IReadOnlyCollection<string>> GetFeaturesUsed()
{
return new [] {new [] {"Imageflow"}};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,9 @@ private RoutingBuilder CreateRoutes(RoutingBuilder builder, List<IPathMapping> m
(IPathMapping)new PathMapping(a.VirtualPath, a.PhysicalPath, a.IgnorePrefixCase)).ToList()));
}

#pragma warning disable CS0618 // Type or member is obsolete
var blobProviders = serverContainer.GetService<IEnumerable<IBlobProvider>>()?.ToList();
#pragma warning restore CS0618 // Type or member is obsolete
var blobWrapperProviders = serverContainer.GetService<IEnumerable<IBlobWrapperProvider>>()?.ToList();
if (blobProviders?.Count > 0 || blobWrapperProviders?.Count > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public EnqueueResult Queue(T taskItem, Func<T, CancellationToken, Task> taskProc
/// <returns></returns>
public Task AwaitAllCurrentTasks()
{
var tasks = c.Values.Select(w => w.GetTask()).Where(w => w != null).ToArray();
var tasks = c.Values.Select(w => w.GetTask()).Where(w => w != null).Cast<Task>().ToArray();
return Task.WhenAll(tasks);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma warning disable CS0618 // Type or member is obsolete
namespace Imazen.Common.Extensibility.StreamCache
{
[Obsolete("Implement IBlobReusable instead")]
Expand Down
125 changes: 64 additions & 61 deletions src/Imazen.Common/Instrumentation/GlobalPerf.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,41 @@ namespace Imazen.Common.Instrumentation
// https://github.com/maiwald/lz-string-ruby
internal class GlobalPerf
{
readonly IssueSink sink = new IssueSink("GlobalPerf");
readonly IssueSink sink = new("GlobalPerf");

public static GlobalPerf Singleton { get; } = new GlobalPerf();
public static GlobalPerf Singleton { get; } = new();

Lazy<BasicProcessInfo> Process { get; } = new Lazy<BasicProcessInfo>();
Lazy<BasicProcessInfo> Process { get; } = new();
Lazy<HardwareInfo> Hardware { get; }

private static ICollection<IInfoProvider> _lastInfoProviders = null;
private static ICollection<IInfoProvider>? _lastInfoProviders;

NamedInterval[] Intervals { get; } = {
new NamedInterval { Unit="second", Name="Per Second", TicksDuration = Stopwatch.Frequency},
new NamedInterval { Unit="minute", Name="Per Minute", TicksDuration = Stopwatch.Frequency * 60},
new NamedInterval { Unit="15_mins", Name="Per 15 Minutes", TicksDuration = Stopwatch.Frequency * 60 * 15},
new NamedInterval { Unit="hour", Name="Per Hour", TicksDuration = Stopwatch.Frequency * 60 * 60},
};
NamedInterval[] Intervals { get; } =
[
new() { Unit="second", Name="Per Second", TicksDuration = Stopwatch.Frequency},
new() { Unit="minute", Name="Per Minute", TicksDuration = Stopwatch.Frequency * 60},
new() { Unit="15_mins", Name="Per 15 Minutes", TicksDuration = Stopwatch.Frequency * 60 * 15},
new() { Unit="hour", Name="Per Hour", TicksDuration = Stopwatch.Frequency * 60 * 60}
];

readonly ConcurrentDictionary<string, MultiIntervalStats> rates = new ConcurrentDictionary<string, MultiIntervalStats>();
readonly ConcurrentDictionary<string, MultiIntervalStats> rates = new();

readonly MultiIntervalStats blobReadEvents;
readonly MultiIntervalStats blobReadBytes;
readonly MultiIntervalStats jobs;
readonly MultiIntervalStats decodedPixels;
readonly MultiIntervalStats encodedPixels;

readonly ConcurrentDictionary<string, IPercentileProviderSink> percentiles = new ConcurrentDictionary<string, IPercentileProviderSink>();
readonly ConcurrentDictionary<string, IPercentileProviderSink> percentiles = new();

readonly IPercentileProviderSink job_times;
readonly IPercentileProviderSink decode_times;
readonly IPercentileProviderSink encode_times;
readonly IPercentileProviderSink job_other_time;
readonly IPercentileProviderSink blob_read_times;
readonly IPercentileProviderSink collect_info_times;
readonly IPercentileProviderSink jobTimes;
readonly IPercentileProviderSink decodeTimes;
readonly IPercentileProviderSink encodeTimes;
readonly IPercentileProviderSink jobOtherTime;
readonly IPercentileProviderSink blobReadTimes;
readonly IPercentileProviderSink collectInfoTimes;

readonly DictionaryCounter<string> counters = new DictionaryCounter<string>("counter_update_failed");
readonly DictionaryCounter<string> counters = new("counter_update_failed");

IEnumerable<int> Percentiles { get; } = new[] { 5, 25, 50, 75, 95, 100 };

Expand All @@ -71,12 +72,12 @@ internal class GlobalPerf
decodedPixels = rates.GetOrAdd("decoded_pixels", new MultiIntervalStats(Intervals));
encodedPixels = rates.GetOrAdd("encoded_pixels", new MultiIntervalStats(Intervals));

job_times = percentiles.GetOrAdd("job_times", new TimingsSink());
decode_times = percentiles.GetOrAdd("decode_times", new TimingsSink());
encode_times = percentiles.GetOrAdd("encode_times", new TimingsSink());
job_other_time = percentiles.GetOrAdd("job_other_time", new TimingsSink());
blob_read_times = percentiles.GetOrAdd("blob_read_times", new TimingsSink());
collect_info_times = percentiles.GetOrAdd("collect_info_times", new TimingsSink());
jobTimes = percentiles.GetOrAdd("job_times", new TimingsSink());
decodeTimes = percentiles.GetOrAdd("decode_times", new TimingsSink());
encodeTimes = percentiles.GetOrAdd("encode_times", new TimingsSink());
jobOtherTime = percentiles.GetOrAdd("job_other_time", new TimingsSink());
blobReadTimes = percentiles.GetOrAdd("blob_read_times", new TimingsSink());
collectInfoTimes = percentiles.GetOrAdd("collect_info_times", new TimingsSink());

sourceMegapixels = percentiles.GetOrAdd("source_pixels", new PixelCountSink());
outputMegapixels = percentiles.GetOrAdd("output_pixels", new PixelCountSink());
Expand All @@ -103,36 +104,36 @@ public void JobComplete(IImageJobInstrumentation job)
IncrementCounter("image_jobs");

var timestamp = Stopwatch.GetTimestamp();
var s_w = job.SourceWidth.GetValueOrDefault(0);
var s_h = job.SourceHeight.GetValueOrDefault(0);
var f_w = job.FinalWidth.GetValueOrDefault(0);
var f_h = job.FinalHeight.GetValueOrDefault(0);
var sW = job.SourceWidth.GetValueOrDefault(0);
var sH = job.SourceHeight.GetValueOrDefault(0);
var fW = job.FinalWidth.GetValueOrDefault(0);
var fH = job.FinalHeight.GetValueOrDefault(0);


if (job.SourceWidth.HasValue && job.SourceHeight.HasValue)
if (job is { SourceWidth: not null, SourceHeight: not null })
{
var prefix = "source_multiple_";
if (s_w % 4 == 0 && s_h % 4 == 0)
if (sW % 4 == 0 && sH % 4 == 0)
{
counters.Increment(prefix + "4x4");
}

if (s_w % 8 == 0 && s_h % 8 == 0)
if (sW % 8 == 0 && sH % 8 == 0)
{
counters.Increment(prefix + "8x8");
}

if (s_w % 8 == 0)
if (sW % 8 == 0)
{
counters.Increment(prefix + "8x");
}

if (s_h % 8 == 0)
if (sH % 8 == 0)
{
counters.Increment(prefix + "x8");
}

if (s_w % 16 == 0 && s_h % 16 == 0)
if (sW % 16 == 0 && sH % 16 == 0)
{
counters.Increment(prefix + "16x16");
}
Expand All @@ -150,37 +151,37 @@ public void JobComplete(IImageJobInstrumentation job)
{
sourceMegapixels.Report(readPixels);

sourceWidths.Report(s_w);
sourceHeights.Report(s_h);
sourceWidths.Report(sW);
sourceHeights.Report(sH);

sourceAspectRatios.Report(s_w * 100 / s_h);
sourceAspectRatios.Report(sW * 100 / sH);
}

if (wrotePixels > 0)
{
outputMegapixels.Report(wrotePixels);


outputWidths.Report(f_w);
outputHeights.Report(f_h);
outputAspectRatios.Report(f_w * 100 / f_h);
outputWidths.Report(fW);
outputHeights.Report(fH);
outputAspectRatios.Report(fW * 100 / fH);
}

if (readPixels > 0 && wrotePixels > 0)
{
scalingRatios.Report(s_w * 100 / f_w);
scalingRatios.Report(s_h * 100 / f_h);
scalingRatios.Report(sW * 100 / fW);
scalingRatios.Report(sH * 100 / fH);
}

jobs.Record(timestamp, 1);
decodedPixels.Record(timestamp, readPixels);
encodedPixels.Record(timestamp, wrotePixels);


job_times.Report(job.TotalTicks);
decode_times.Report(job.DecodeTicks);
encode_times.Report(job.EncodeTicks);
job_other_time.Report(job.TotalTicks - job.DecodeTicks - job.EncodeTicks);
jobTimes.Report(job.TotalTicks);
decodeTimes.Report(job.DecodeTicks);
encodeTimes.Report(job.EncodeTicks);
jobOtherTime.Report(job.TotalTicks - job.DecodeTicks - job.EncodeTicks);

if (job.SourceFileExtension != null)
{
Expand All @@ -195,27 +196,27 @@ public void JobComplete(IImageJobInstrumentation job)
}


readonly ConcurrentDictionary<string, DictionaryCounter<string>> uniques
= new ConcurrentDictionary<string, DictionaryCounter<string>>(StringComparer.Ordinal);
private long CountLimitedUniqueValuesIgnoreCase(string category, string value, int limit, string otherBucketValue)
readonly ConcurrentDictionary<string, DictionaryCounter<string>> uniques = new(StringComparer.Ordinal);

// ReSharper disable once UnusedMethodReturnValue.Local
private long CountLimitedUniqueValuesIgnoreCase(string category, string? value, int limit, string otherBucketValue)
{
return uniques.GetOrAdd(category, (k) =>
return uniques.GetOrAdd(category, (_) =>
new DictionaryCounter<string>(limit, otherBucketValue, StringComparer.OrdinalIgnoreCase))
.Increment(value ?? "null");

}
private IEnumerable<string> GetPopularUniqueValues(string category, int limit)
{
DictionaryCounter<string> v;
return uniques.TryGetValue(category, out v) ?
return uniques.TryGetValue(category, out DictionaryCounter<string>? v) ?
v.GetCounts()
.Where(pair => pair.Value > 0)
.OrderByDescending(pair => pair.Value)
.Take(limit).Select(pair => pair.Key) :
Enumerable.Empty<string>();
}

private void NoticeDomains(string imageDomain, string pageDomain)
private void NoticeDomains(string? imageDomain, string? pageDomain)
{
if (imageDomain != null) {
CountLimitedUniqueValuesIgnoreCase("image_domains", imageDomain, 45, "_other_");
Expand All @@ -226,8 +227,9 @@ private void NoticeDomains(string imageDomain, string pageDomain)
}
}

private void PostJobQuery(IEnumerable<string> querystringKeys)
private void PostJobQuery(IEnumerable<string>? querystringKeys)
{
if (querystringKeys == null) return;
foreach (var key in querystringKeys)
{
if (key != null)
Expand All @@ -237,8 +239,9 @@ private void PostJobQuery(IEnumerable<string> querystringKeys)
}
}

public void PreRewriteQuery(IEnumerable<string> querystringKeys)
public void PreRewriteQuery(IEnumerable<string>? querystringKeys)
{
if (querystringKeys == null) return;
foreach (var key in querystringKeys)
{
if (key != null)
Expand All @@ -252,7 +255,7 @@ public static void BlobRead(long ticks, long bytes)
{
Singleton.blobReadEvents.Record(Stopwatch.GetTimestamp(), 1);
Singleton.blobReadBytes.Record(Stopwatch.GetTimestamp(), bytes);
Singleton.blob_read_times.Report(ticks);
Singleton.blobReadTimes.Report(ticks);
}

public IInfoAccumulator GetReportPairs()
Expand Down Expand Up @@ -282,8 +285,8 @@ public IInfoAccumulator GetReportPairs()
q.Add(rate.Key + "_total", rate.Value.RecordedTotal);
foreach (var pair in rate.Value.GetStats())
{
var basekey = rate.Key + "_per_" + pair.Interval.Unit;
q.Add(basekey + "_max", pair.Max);
var baseKey = rate.Key + "_per_" + pair.Interval.Unit;
q.Add(baseKey + "_max", pair.Max);
}
}

Expand Down Expand Up @@ -312,13 +315,13 @@ public IInfoAccumulator GetReportPairs()
string.Join(",", GetPopularUniqueValues("job_query_keys", 40).Except(originalKeys).Take(2)));

timeThis.Stop();
collect_info_times.Report(timeThis.ElapsedTicks);
collectInfoTimes.Report(timeThis.ElapsedTicks);
return q;
}

public void TrackRate(string eventCategoryKey, long count)
{
rates.GetOrAdd(eventCategoryKey, (k) => new MultiIntervalStats(Intervals)).Record(Stopwatch.GetTimestamp(), count);
rates.GetOrAdd(eventCategoryKey, (_) => new MultiIntervalStats(Intervals)).Record(Stopwatch.GetTimestamp(), count);
}

public void IncrementCounter(string key)
Expand Down
4 changes: 2 additions & 2 deletions src/Imazen.Common/Instrumentation/IImageJobInstrumentation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal interface IImageJobInstrumentation
/// <summary>
/// var ext = PathUtils.GetExtension(job.SourcePathData).ToLowerInvariant().TrimStart('.');
/// </summary>
string SourceFileExtension { get; }
string? SourceFileExtension { get; }

/// <summary>
/// request?.Url?.DnsSafeHost
Expand All @@ -26,7 +26,7 @@ internal interface IImageJobInstrumentation
/// </summary>
string? PageDomain { get; }

IEnumerable<string> FinalCommandKeys { get; }
IEnumerable<string>? FinalCommandKeys { get; }

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ internal class SegmentClamping
public long MaxPossibleValues { get; set; } = 100000;
public long MinValue { get; set; } = 0;
public long MaxValue { get; set; } = long.MaxValue;
public SegmentPrecision[] Segments { get; set; }
public required SegmentPrecision[] Segments { get; set; }

public void Sort()
{
Expand Down
10 changes: 4 additions & 6 deletions src/Imazen.Common/Instrumentation/Support/DictionaryCounter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Imazen.Common.Instrumentation.Support
{
class DictionaryCounter<T>
class DictionaryCounter<T> where T : notnull
{
readonly ConcurrentDictionary<T, Counter> dict;
readonly Counter count;
Expand Down Expand Up @@ -36,8 +36,7 @@ public DictionaryCounter(int maxKeyCount, T limitExceededKey, IEnumerable<KeyVal

public bool TryRead(T key, out long v)
{
Counter c;
if (dict.TryGetValue(key, out c))
if (dict.TryGetValue(key, out var c))
{
v = c.Value;
return true;
Expand All @@ -56,9 +55,8 @@ public bool Contains(T key)

Counter GetOrAddInternal(T key, long initialValue, bool applyLimitSwap)
{
for (var retryCount = 0; retryCount < 10; retryCount++) {
Counter result;
if (dict.TryGetValue(key, out result))
for (var retryCount = 0; retryCount < 10; retryCount++) {
if (dict.TryGetValue(key, out var result))
{
return result;
} else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ public interface IInfoAccumulator
void AddString(string key, string? value);
IInfoAccumulator WithPrefix(string prefix);
IInfoAccumulator WithPrepend(bool prepend);
IEnumerable<KeyValuePair<string, string>> GetInfo();
IEnumerable<KeyValuePair<string, string?>> GetInfo();
}
}
Loading

0 comments on commit e51f9ec

Please sign in to comment.