Skip to content

Singlefile compression of native files - #49855

Merged
14 commits merged into
dotnet:mainfrom
VSadov:compression
Mar 29, 2021
Merged

Singlefile compression of native files#49855
14 commits merged into
dotnet:mainfrom
VSadov:compression

Conversation

@VSadov

@VSadov VSadov commented Mar 19, 2021

Copy link
Copy Markdown
Member

First part of implementing compression in singlefile apps.

In this change:

  • introducing compression support in Bundler and annotation for compressed files in the header.
  • the scheme is used for native an symbol files (compressing managed assemblies is not in this change)
  • decompression support in extractor.
  • additional option for Bundler to toggle support for compression.
    Current use is only in tests. Eventually SDK will use this flag, also plans for exposing the flag in msbuild.
  • current default is no-compression. What default will be chosen in SDK is TBD.

@ghost ghost added the area-Single-File label Mar 19, 2021
@ghost

ghost commented Mar 19, 2021

Copy link
Copy Markdown

Tagging subscribers to this area: @agocke, @vitek-karas, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

In progress, just running tests

Author: VSadov
Assignees: -
Labels:

area-Single-File

Milestone: -

Comment thread src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
Comment thread src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs Outdated
Comment thread src/installer/managed/Microsoft.NET.HostModel/Bundle/FileEntry.cs Outdated
@VSadov
VSadov marked this pull request as ready for review March 22, 2021 20:02
@VSadov

VSadov commented Mar 23, 2021

Copy link
Copy Markdown
Member Author

I think this PR has everything that I planned for this part.
@vitek-karas could you take another look? Thanks!

Comment thread src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs Outdated
Comment thread src/native/corehost/bundle/header.h
Comment thread src/native/corehost/hostmisc/utils.h
Comment thread src/native/corehost/bundle/file_entry.h
Version targetFrameworkVersion = null)
{
UseSingleFileSelfContainedHost(testFixture);
options |= BundleOptions.EnableCompression;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should also add a couple of tests which disable compression on purpose. I know we expect compression to be on by default, but will allow users to disable it, so we should validate that it works.

@VSadov VSadov Mar 25, 2021

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Some files are not compressed, and .json never will be, so the case with uncompressed files is validated.
Turning off compression intentionally in one of self-contained tests is an easy thing to do though.

@VSadov

VSadov commented Mar 27, 2021

Copy link
Copy Markdown
Member Author

@vitek-karas - I think I have addressed all the concerns. Let me know if I missed something.

@vitek-karas vitek-karas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Some comments, but nothing major... looks good!

using System.IO;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;
using System.IO.Compression;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: sort usings

Comment thread src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
Comment on lines 62 to 64
UseSingleFileSelfContainedHost(fixture);
options |= BundleOptions.EnableCompression;
var singleFile = BundleHelper.BundleApp(fixture, options);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Given that we plan to have this on by default - I would probably change the default test behavior as well. Make the BundleHelper turn on compression by default and have a way for the test to selectively disable it.

@VSadov VSadov Mar 29, 2021

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

From the perspective of the Bundler compression will be off by default. That is because the Bundler does not know if we use framework-dependent bundle and it would be a dangerous default.
I think BundleHelper should default to "off" for the same reasons. Compression must be an opt-in feature at the bundler level. SDK can have different defaults since it has more information.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree to a point - basically if I add a new test - I will definitely forget to set this option - and thus my test will not cover the most common scenario. Given the history of bad and few tests in this area I'd like to make it so that we have at least reasonable coverage for the most common cases.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I have explored making UseSingleFileSelfContainedHost to enable compression automatically, but it was not very natural since the “fixture” stuff operates at proj file level and does not know much about the bundle.

Perhaps I should revisit that direction. Maybe set a flag on the fixture, that BundleHelper would read.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nope going further that direction only make things worse. If UseSingleFileSelfContainedHost sets "can do compression" flag, then there are two ways to specify whether compression is desired - because fixture says so and via flags passed to bundler. The flag on the fixture must take precedence and that is a bit unintuitive and could be error prone if fixture is reused. Also for the unusual/error cases I would need another argument to override the override. It gets messy.

Here what seems to work better.

  • Add a helper BundleSelfContainedApp which both picks the right host and then adds compression flags and passes that to Bundler.
  • Make all tests that could use BundleSelfContainedApp use it - that is nearly all tests that do singlefile stuff.
  • A a few tests that need to tests unusual/error combinations go the long route - they will have to use UseSingleFileSelfContainedHost and explicitly and have spell out what they need in terms of compression to BundleApp. There are only a few tests like that.

I would expect the obvious difference in verbosity will direct future testcase writers towards the "default" path.

Comment thread src/native/corehost/bundle/file_entry.cpp Outdated
@vitek-karas
vitek-karas requested a review from mateoatr March 29, 2021 10:24
@vitek-karas

Copy link
Copy Markdown
Member

@mateoatr could you please also take a look. It's a relatively major change so it would be best to have multiple people look at it. I'm especially nervous about the versioning and compat behaviors (always a tricky topic).

Comment thread src/installer/managed/Microsoft.NET.HostModel/Bundle/Bundler.cs
Comment thread src/native/corehost/bundle/extractor.cpp Outdated
Comment thread src/native/corehost/bundle/extractor.cpp Outdated
{
var fixture = sharedTestState.TestSelfContainedFixture.Copy();
UseSingleFileSelfContainedHost(fixture);
options |= BundleOptions.EnableCompression;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we have something similar in NetCoreApp3CompatModeTests?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Per @vitek-karas suggestion I am making compression a default behavior in all singlefile tests. Only few tests will explicitly use singlefilehost and no compression.
I think it will take care of this as well.

@VSadov
VSadov requested a review from mateoatr March 29, 2021 23:00

@mateoatr mateoatr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@VSadov

VSadov commented Mar 29, 2021

Copy link
Copy Markdown
Member Author

Thanks!!

@ghost

ghost commented Mar 29, 2021

Copy link
Copy Markdown

Hello @VSadov!

Because this pull request has the auto-merge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost
ghost merged commit 857fe5b into dotnet:main Mar 29, 2021
@VSadov
VSadov deleted the compression branch March 29, 2021 23:17
@jjxtra

jjxtra commented Mar 30, 2021

Copy link
Copy Markdown

Adding lzma compression in the future would be interesting, further reducing size at the cost of slightly longer build time and slightly longer decompression times.

@ghost ghost locked as resolved and limited conversation to collaborators Apr 29, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants