Skip to content

Commit

Permalink
Merge pull request #305 from SixLabors/js/imagesharpV3
Browse files Browse the repository at this point in the history
Update to Imagesharp v3
  • Loading branch information
JimBobSquarePants authored Mar 5, 2023
2 parents d91883f + bc1e923 commit e852621
Show file tree
Hide file tree
Showing 84 changed files with 346 additions and 333 deletions.
5 changes: 3 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,19 @@
# Set explicit file behavior to:
# treat as text
# normalize to Unix-style line endings and
# use a union merge when resoling conflicts
# use a union merge when resolving conflicts
###############################################################################
*.csproj text eol=lf merge=union
*.dbproj text eol=lf merge=union
*.fsproj text eol=lf merge=union
*.ncrunchproject text eol=lf merge=union
*.vbproj text eol=lf merge=union
*.shproj text eol=lf merge=union
###############################################################################
# Set explicit file behavior to:
# treat as text
# normalize to Windows-style line endings and
# use a union merge when resoling conflicts
# use a union merge when resolving conflicts
###############################################################################
*.sln text eol=crlf merge=union
###############################################################################
Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,15 @@ jobs:
shell: pwsh
run: ./ci-pack.ps1

- name: MyGet Publish
- name: Feedz Publish
shell: pwsh
run: |
dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.MYGET_TOKEN}} -s https://www.myget.org/F/sixlabors/api/v2/package
dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.MYGET_TOKEN}} -s https://www.myget.org/F/sixlabors/api/v3/index.json
# TODO: If github.ref starts with 'refs/tags' then it was tag push and we can optionally push out package to nuget.org
dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.FEEDZ_TOKEN}} -s https://f.feedz.io/sixlabors/sixlabors/nuget/index.json --skip-duplicate
dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.FEEDZ_TOKEN}} -s https://f.feedz.io/sixlabors/sixlabors/symbols --skip-duplicate
- name: NuGet Publish
if: ${{ startsWith(github.ref, 'refs/tags/') }}
shell: pwsh
run: |
dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ For more information, see the [.NET Foundation Code of Conduct](https://dotnetfo

### Installation

Install stable releases via Nuget; development releases are available via MyGet.
Install stable releases via Nuget; development releases are available via Feedz.io.

| Package Name | Release (NuGet) | Nightly (MyGet) |
| Package Name | Release (NuGet) | Nightly (Feedz.io) |
|--------------------------------|-----------------|-----------------|
| `SixLabors.ImageSharp.Web` | [![NuGet](https://img.shields.io/nuget/v/SixLabors.ImageSharp.Web.svg)](https://www.nuget.org/packages/SixLabors.ImageSharp.Web/) | [![MyGet](https://img.shields.io/myget/sixlabors/vpre/SixLabors.ImageSharp.Web.svg)](https://www.myget.org/feed/sixlabors/package/nuget/SixLabors.ImageSharp.Web) |
| `SixLabors.ImageSharp.Web` | [![NuGet](https://img.shields.io/nuget/v/SixLabors.ImageSharp.Web.svg)](https://www.nuget.org/packages/SixLabors.ImageSharp.Web/) | [![feedz.io](https://img.shields.io/badge/endpoint.svg?url=https%3A%2F%2Ff.feedz.io%2Fsixlabors%2Fsixlabors%2Fshield%2FSixLabors.ImageSharp.Web%2Flatest)](https://f.feedz.io/sixlabors/sixlabors/nuget/index.json) |

## Manual build

Expand Down
2 changes: 1 addition & 1 deletion ci-pack.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ dotnet clean -c Release
$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY"

# Building for packing and publishing.
dotnet pack -c Release --output "$PSScriptRoot/artifacts" /p:RepositoryUrl=$repositoryUrl
dotnet pack -c Release -p:PackageOutputPath="$PSScriptRoot/artifacts" -p:RepositoryUrl=$repositoryUrl
88 changes: 37 additions & 51 deletions samples/ImageSharp.Web.Sample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,50 +30,44 @@ public class Startup
/// </summary>
/// <param name="services">The collection of service descriptors.</param>
public void ConfigureServices(IServiceCollection services)
{
services.AddImageSharp()
.SetRequestParser<QueryCollectionRequestParser>()
.Configure<PhysicalFileSystemCacheOptions>(options =>
{
options.CacheRootPath = null;
options.CacheFolder = "is-cache";
options.CacheFolderDepth = 8;
})
.SetCache<PhysicalFileSystemCache>()
.SetCacheKey<UriRelativeLowerInvariantCacheKey>()
.SetCacheHash<SHA256CacheHash>()
.Configure<PhysicalFileSystemProviderOptions>(options =>
{
options.ProviderRootPath = null;
})
.AddProvider<PhysicalFileSystemProvider>()
.AddProcessor<ResizeWebProcessor>()
.AddProcessor<FormatWebProcessor>()
.AddProcessor<BackgroundColorWebProcessor>()
.AddProcessor<QualityWebProcessor>()
.AddProcessor<AutoOrientWebProcessor>();
=> services.AddImageSharp()
.SetRequestParser<QueryCollectionRequestParser>()
.Configure<PhysicalFileSystemCacheOptions>(options =>
{
options.CacheRootPath = null;
options.CacheFolder = "is-cache";
options.CacheFolderDepth = 8;
})
.SetCache<PhysicalFileSystemCache>()
.SetCacheKey<UriRelativeLowerInvariantCacheKey>()
.SetCacheHash<SHA256CacheHash>()
.Configure<PhysicalFileSystemProviderOptions>(options => options.ProviderRootPath = null)
.AddProvider<PhysicalFileSystemProvider>()
.AddProcessor<ResizeWebProcessor>()
.AddProcessor<FormatWebProcessor>()
.AddProcessor<BackgroundColorWebProcessor>()
.AddProcessor<QualityWebProcessor>()
.AddProcessor<AutoOrientWebProcessor>();

// Add the default service and options.
//
// services.AddImageSharp();
// Add the default service and options.
//
// services.AddImageSharp();

// Or add the default service and custom options.
//
// this.ConfigureDefaultServicesAndCustomOptions(services);
// Or add the default service and custom options.
//
// this.ConfigureDefaultServicesAndCustomOptions(services);

// Or we can fine-grain control adding the default options and configure all other services.
//
// this.ConfigureCustomServicesAndDefaultOptions(services);
// Or we can fine-grain control adding the default options and configure all other services.
//
// this.ConfigureCustomServicesAndDefaultOptions(services);

// Or we can fine-grain control adding custom options and configure all other services
// There are also factory methods for each builder that will allow building from configuration files.
//
// this.ConfigureCustomServicesAndCustomOptions(services);
}
// Or we can fine-grain control adding custom options and configure all other services
// There are also factory methods for each builder that will allow building from configuration files.
//
// this.ConfigureCustomServicesAndCustomOptions(services);

private void ConfigureDefaultServicesAndCustomOptions(IServiceCollection services)
{
services.AddImageSharp(options =>
=> services.AddImageSharp(options =>
{
options.Configuration = Configuration.Default;
options.BrowserMaxAge = TimeSpan.FromDays(7);
Expand All @@ -84,18 +78,14 @@ private void ConfigureDefaultServicesAndCustomOptions(IServiceCollection service
options.OnProcessedAsync = _ => Task.CompletedTask;
options.OnPrepareResponseAsync = _ => Task.CompletedTask;
});
}

private void ConfigureCustomServicesAndDefaultOptions(IServiceCollection services)
{
services.AddImageSharp()
.RemoveProcessor<FormatWebProcessor>()
.RemoveProcessor<BackgroundColorWebProcessor>();
}
=> services.AddImageSharp()
.RemoveProcessor<FormatWebProcessor>()
.RemoveProcessor<BackgroundColorWebProcessor>();

private void ConfigureCustomServicesAndCustomOptions(IServiceCollection services)
{
services.AddImageSharp(options =>
=> services.AddImageSharp(options =>
{
options.Configuration = Configuration.Default;
options.BrowserMaxAge = TimeSpan.FromDays(7);
Expand All @@ -107,10 +97,7 @@ private void ConfigureCustomServicesAndCustomOptions(IServiceCollection services
options.OnPrepareResponseAsync = _ => Task.CompletedTask;
})
.SetRequestParser<QueryCollectionRequestParser>()
.Configure<PhysicalFileSystemCacheOptions>(options =>
{
options.CacheFolder = "different-cache";
})
.Configure<PhysicalFileSystemCacheOptions>(options => options.CacheFolder = "different-cache")
.SetCache<PhysicalFileSystemCache>()
.SetCacheKey<UriRelativeLowerInvariantCacheKey>()
.SetCacheHash<SHA256CacheHash>()
Expand All @@ -121,7 +108,6 @@ private void ConfigureCustomServicesAndCustomOptions(IServiceCollection services
.AddProcessor<FormatWebProcessor>()
.AddProcessor<BackgroundColorWebProcessor>()
.AddProcessor<QualityWebProcessor>();
}

/// <summary>
/// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
2 changes: 1 addition & 1 deletion shared-infrastructure
5 changes: 3 additions & 2 deletions src/ImageSharp.Web.Providers.AWS/AmazonS3ClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal static class AmazonS3ClientFactory
/// <returns>
/// A new <see cref="AmazonS3Client"/>.
/// </returns>
/// <exception cref="ArgumentException">Invalid configuration.</exception>
public static AmazonS3Client CreateClient(IAWSS3BucketClientOptions options)
{
if (!string.IsNullOrWhiteSpace(options.Endpoint))
Expand All @@ -33,14 +34,14 @@ public static AmazonS3Client CreateClient(IAWSS3BucketClientOptions options)
{
// AccessSecret can be empty.
Guard.NotNullOrWhiteSpace(options.Region, nameof(options.Region));
var region = RegionEndpoint.GetBySystemName(options.Region);
RegionEndpoint region = RegionEndpoint.GetBySystemName(options.Region);
AmazonS3Config config = new() { RegionEndpoint = region, UseAccelerateEndpoint = options.UseAccelerateEndpoint };
SetTimeout(config, options.Timeout);
return new AmazonS3Client(options.AccessKey, options.AccessSecret, config);
}
else if (!string.IsNullOrWhiteSpace(options.Region))
{
var region = RegionEndpoint.GetBySystemName(options.Region);
RegionEndpoint region = RegionEndpoint.GetBySystemName(options.Region);
AmazonS3Config config = new() { RegionEndpoint = region, UseAccelerateEndpoint = options.UseAccelerateEndpoint };
SetTimeout(config, options.Timeout);
return new AmazonS3Client(config);
Expand Down
1 change: 0 additions & 1 deletion src/ImageSharp.Web/AsyncHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using System.Globalization;

Expand Down
1 change: 0 additions & 1 deletion src/ImageSharp.Web/Caching/HexEncoder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
Expand Down
1 change: 0 additions & 1 deletion src/ImageSharp.Web/Caching/ICacheHash.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

namespace SixLabors.ImageSharp.Web.Caching;

Expand Down
1 change: 0 additions & 1 deletion src/ImageSharp.Web/Caching/ICacheKey.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using Microsoft.AspNetCore.Http;
using SixLabors.ImageSharp.Web.Commands;
Expand Down
3 changes: 1 addition & 2 deletions src/ImageSharp.Web/Caching/IImageCache.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using SixLabors.ImageSharp.Web.Resolvers;

Expand All @@ -17,7 +16,7 @@ public interface IImageCache
/// </summary>
/// <param name="key">The cache key.</param>
/// <returns>The <see cref="IImageResolver"/>.</returns>
Task<IImageCacheResolver> GetAsync(string key);
Task<IImageCacheResolver?> GetAsync(string key);

/// <summary>
/// Sets the value associated with the specified key.
Expand Down
1 change: 0 additions & 1 deletion src/ImageSharp.Web/Caching/LegacyV1CacheKey.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using System.Globalization;
using System.Text;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace SixLabors.ImageSharp.Web.Caching;
Expand All @@ -26,6 +26,7 @@ namespace SixLabors.ImageSharp.Web.Caching;
/// 6. When cold is full, cold tail is moved to warm head or removed from dictionary on depending on WasAccessed.
/// </remarks>
internal class ConcurrentTLruCache<TKey, TValue>
where TKey : notnull
{
private readonly ConcurrentDictionary<TKey, LongTickCountLruItem<TKey, TValue>> dictionary;

Expand Down Expand Up @@ -97,9 +98,9 @@ public ConcurrentTLruCache(int concurrencyLevel, int capacity, IEqualityComparer
/// <param name="key">The key of the value to get.</param>
/// <param name="value">When this method returns, contains the object from the cache that has the specified key, or the default value of the type if the operation failed.</param>
/// <returns><see langword="true"/> if the key was found in the cache; otherwise, <see langword="false"/>.</returns>
public bool TryGet(TKey key, out TValue value)
public bool TryGet(TKey key, [NotNullWhen(true)] out TValue? value)
{
if (this.dictionary.TryGetValue(key, out LongTickCountLruItem<TKey, TValue> item))
if (this.dictionary.TryGetValue(key, out LongTickCountLruItem<TKey, TValue>? item))
{
return this.GetOrDiscard(item, out value);
}
Expand All @@ -111,7 +112,7 @@ public bool TryGet(TKey key, out TValue value)
// AggressiveInlining forces the JIT to inline policy.ShouldDiscard(). For LRU policy
// the first branch is completely eliminated due to JIT time constant propogation.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool GetOrDiscard(LongTickCountLruItem<TKey, TValue> item, out TValue value)
private bool GetOrDiscard(LongTickCountLruItem<TKey, TValue> item, out TValue? value)
{
if (this.policy.ShouldDiscard(item))
{
Expand All @@ -135,7 +136,7 @@ private bool GetOrDiscard(LongTickCountLruItem<TKey, TValue> item, out TValue va
/// in the cache, or the new value if the key was not in the dictionary.</returns>
public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
if (this.TryGet(key, out TValue value))
if (this.TryGet(key, out TValue? value))
{
return value;
}
Expand Down Expand Up @@ -164,7 +165,7 @@ public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
/// <returns>A task that represents the asynchronous <see cref="GetOrAdd(TKey, Func{TKey, TValue})"/> operation.</returns>
public async Task<TValue> GetOrAddAsync(TKey key, Func<TKey, Task<TValue>> valueFactory)
{
if (this.TryGet(key, out TValue value))
if (this.TryGet(key, out TValue? value))
{
return value;
}
Expand Down Expand Up @@ -202,7 +203,7 @@ public bool TryRemove(TKey key)
// and it will not be marked as removed. If key 1 is fetched while LruItem1* is still in the queue, there will
// be two queue entries for key 1, and neither is marked as removed. Thus when LruItem1 * ages out, it will
// incorrectly remove 1 from the dictionary, and this cycle can repeat.
if (this.dictionary.TryGetValue(key, out LongTickCountLruItem<TKey, TValue> existing))
if (this.dictionary.TryGetValue(key, out LongTickCountLruItem<TKey, TValue>? existing))
{
if (existing.WasRemoved)
{
Expand All @@ -219,7 +220,7 @@ public bool TryRemove(TKey key)
existing.WasRemoved = true;
}

if (this.dictionary.TryRemove(key, out LongTickCountLruItem<TKey, TValue> removedItem))
if (this.dictionary.TryRemove(key, out LongTickCountLruItem<TKey, TValue>? removedItem))
{
// Mark as not accessed, it will later be cycled out of the queues because it can never be fetched
// from the dictionary. Note: Hot/Warm/Cold count will reflect the removed item until it is cycled
Expand Down Expand Up @@ -261,7 +262,7 @@ private void CycleHot()
{
Interlocked.Decrement(ref this.hotCount);

if (this.hotQueue.TryDequeue(out LongTickCountLruItem<TKey, TValue> item))
if (this.hotQueue.TryDequeue(out LongTickCountLruItem<TKey, TValue>? item))
{
ItemDestination where = this.policy.RouteHot(item);
this.Move(item, where);
Expand All @@ -279,7 +280,7 @@ private void CycleWarm()
{
Interlocked.Decrement(ref this.warmCount);

if (this.warmQueue.TryDequeue(out LongTickCountLruItem<TKey, TValue> item))
if (this.warmQueue.TryDequeue(out LongTickCountLruItem<TKey, TValue>? item))
{
ItemDestination where = this.policy.RouteWarm(item);

Expand Down Expand Up @@ -308,7 +309,7 @@ private void CycleCold()
{
Interlocked.Decrement(ref this.coldCount);

if (this.coldQueue.TryDequeue(out LongTickCountLruItem<TKey, TValue> item))
if (this.coldQueue.TryDequeue(out LongTickCountLruItem<TKey, TValue>? item))
{
ItemDestination where = this.policy.RouteCold(item);

Expand Down Expand Up @@ -354,7 +355,7 @@ private void Move(LongTickCountLruItem<TKey, TValue> item, ItemDestination where
break;
}

if (this.dictionary.TryRemove(item.Key, out LongTickCountLruItem<TKey, TValue> removedItem))
if (this.dictionary.TryRemove(item.Key, out LongTickCountLruItem<TKey, TValue>? removedItem))
{
item.WasRemoved = true;
if (removedItem.Value is IDisposable d)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

namespace SixLabors.ImageSharp.Web.Caching;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable

using System.Diagnostics;
using System.Runtime.CompilerServices;
Expand Down
Loading

0 comments on commit e852621

Please sign in to comment.