Skip to content

Conversation

@antonfirsov
Copy link
Member

@antonfirsov antonfirsov commented Jul 31, 2020

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following matches the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Breaking changes

  • Image.LoadAsync(...), Image.IdentifyAsync(...), image.SaveAsync(...), image.SaveAsXyzAsync(...) overloads replaced by cancellable variants, with default argument cancellationToken = default
  • Async overloads on IImageEncoder, IImageDecoder and IImageVisitor replaced by cancellable variants

Description

  • Refactor duplicate code out from decoders and encoders into ImageDecoderUtilities and ImageEncoderUtilities
  • Make IImageEncoder and IImageDecoder cancellable.
    • To make the expensive codec logic cancellable, a CancellationToken is forwarded to the synchronous internal implementation classes (IImageDecoderInternals and IImageEncoderInternals implementors)
  • Cancellation is actually implemented and tested for Jpeg
  • Add a bunch of new (cancellable & non-cancellable) overloads for Image.LoadAsync and Image.IdentifyAsync together with tests
  • The Formats/*/ImageExtensions.cs files containing the .SaveAs* methods became unmaintainable with the exponential growth of parameters. Replacing them with generated code coming from ImageExtesions.Save.tt.

This is a relatively large change right before releasing 1.0 (😅), so hoping for an thorough review to minimize risks.

Resolves #1280.

@antonfirsov antonfirsov requested a review from a team July 31, 2020 00:38
@antonfirsov antonfirsov added this to the 1.0.0 milestone Jul 31, 2020
@antonfirsov antonfirsov changed the title Cancellable codecs and missing overloads Cancellable codec API, and missing overloads for loading/saving Jul 31, 2020
@antonfirsov antonfirsov changed the title Cancellable codec API, and missing overloads for loading/saving Cancellable codec API, and overloads for loading/saving Jul 31, 2020
Copy link
Member

@tocsoft tocsoft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a couple of things

As a rule for any async methods I feel we should have this guidance:

  1. Don't have multiple overloads which only differ on having a CancellationToken or not.
  2. Public apis should always have the cancellation token, and it should be configured with a default value of default
  3. Internal/private apis should never have a default value for the CancellationToken (to make it harder to miss passing a public token along)


using var bufferedStream = new BufferedReadStream(configuration, stream);
return decoder.IdentifyAsync(bufferedStream);
return await decoder.IdentifyAsync(configuration, bufferedStream, cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as we are awaiting here this one should have a .ConfigureAwait(false)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this actually needs awaiting does it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do because of the use of the buffered stream

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should double check elsewhere then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will check if I can solve by adding a helper method.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to create a BufferedReadStream in this method, so it can be simplified and the async context removed.

Copy link
Member

@JimBobSquarePants JimBobSquarePants left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor things... Very impressed though, it's cool!


using var bufferedStream = new BufferedReadStream(configuration, stream);
return decoder.IdentifyAsync(bufferedStream);
return await decoder.IdentifyAsync(configuration, bufferedStream, cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this actually needs awaiting does it?

@antonfirsov
Copy link
Member Author

@tocsoft @JimBobSquarePants ready for final review.

@codecov
Copy link

codecov bot commented Aug 4, 2020

Codecov Report

Merging #1296 into master will increase coverage by 0.07%.
The diff coverage is 88.65%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1296      +/-   ##
==========================================
+ Coverage   82.71%   82.79%   +0.07%     
==========================================
  Files         692      689       -3     
  Lines       30718    30731      +13     
  Branches     3474     3472       -2     
==========================================
+ Hits        25409    25444      +35     
+ Misses       4603     4581      -22     
  Partials      706      706              
Flag Coverage Δ
#unittests 82.79% <88.65%> (+0.07%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs 94.45% <ø> (ø)
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs 96.66% <ø> (-0.19%) ⬇️
src/ImageSharp/Formats/Gif/GifDecoderCore.cs 83.96% <ø> (ø)
src/ImageSharp/Formats/Gif/GifEncoderCore.cs 95.05% <ø> (-0.16%) ⬇️
src/ImageSharp/Formats/Png/PngDecoderCore.cs 90.44% <ø> (ø)
src/ImageSharp/Formats/Png/PngEncoderCore.cs 97.81% <ø> (-0.05%) ⬇️
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs 91.29% <ø> (ø)
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs 99.31% <ø> (-0.05%) ⬇️
src/ImageSharp/Formats/Gif/GifDecoder.cs 58.82% <33.33%> (+8.82%) ⬆️
src/ImageSharp/Formats/Png/PngDecoder.cs 50.00% <33.33%> (+1.85%) ⬆️
... and 29 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 586d99e...e707a8d. Read the comment docs.

@antonfirsov antonfirsov added the breaking Signifies a binary breaking change. label Aug 4, 2020
Copy link
Member

@JimBobSquarePants JimBobSquarePants left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found and fixed a couple of issues where we needed to await IDisposable's but otherwise LGTM 👍

@JimBobSquarePants JimBobSquarePants merged commit 521fae3 into master Aug 4, 2020
@JimBobSquarePants JimBobSquarePants deleted the af/cancellation branch August 4, 2020 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API breaking Signifies a binary breaking change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add public API changes necessary for cancellation support for LoadAsync/SaveAsync

4 participants