Skip to content

Http file streaming#218

Closed
dotMorten wants to merge 10 commits into
microsoft:masterfrom
dotMorten:HttpFileStreaming
Closed

Http file streaming#218
dotMorten wants to merge 10 commits into
microsoft:masterfrom
dotMorten:HttpFileStreaming

Conversation

@dotMorten
Copy link
Copy Markdown
Contributor

This is a first stab at using a custom http multipart content to avoid large memory consumption when installing large files.

Please DO NOT merge this yet. It needs some significant testing for the InstallApplicationAsync call, and I don't have all the scenarios currently available to test them all. I'm submitting this for issue #141 and asking for people to please give this a go and test it.

The UWP and .NET implementations are quite different and would need separate testing.

@WilliamsJason
Copy link
Copy Markdown
Contributor

I'm starting to look at this finally. For a small appx with a single dependency on Xbox it succeeded but for a larger package it's failing with the following: Cannot access a disposed object.
Object name: 'SslStream'. This is on the line that copies the file to the outStream (await file.CopyToAsync(outStream); in HttpMultipartFileContent's SerializeToStreamAsync).

Still digging in, but I'll try to give you info as I get it in case you know what the issue is and how to address it.

@dotMorten
Copy link
Copy Markdown
Contributor Author

There's a pretty good description of the problem in this PR: aspnet/KestrelHttpServer#750.
Sounds like the connection was closed and we just need to try/catch it.
However that probably doesn't fix the issue (why was the connection closed?). I have noticed requests are often made twice, probably an unauthenticated one and then an authenticated one. Could be this is just getting rejected first time around?

@WilliamsJason
Copy link
Copy Markdown
Contributor

Hmm. That's on the response though. This is failing while setting up the request still. I also noticed that sometimes it's an abort exception instead of the disposed exception. I think something is closing the out stream that we are copying the file to after a pretty good number of bytes. I'll try a few more things.

@WilliamsJason
Copy link
Copy Markdown
Contributor

I tried with a few different buffer sizes on the CopyToAsync of the large appx (up to a 1 GB buffer), but no luck. It super consistently fails at the same duration per buffer size though--slightly different duration for each buffer size but around 1.5 minutes for all of them. Could be a certain part of the appx file or count of bytes, could be something else.

@dotMorten
Copy link
Copy Markdown
Contributor Author

dotMorten commented Feb 27, 2017

I tried 4Gb last night in UWP, and it uploaded fine, and memory consumption stayed around 15mb (but failed install which could have been a different reason. Didn't get a chance to dive in why yet, since the file copy over 2GHz wifi took a looooong time, and I needed to go to bed :-)

Copy link
Copy Markdown

@david-c-kline david-c-kline left a comment

Choose a reason for hiding this comment

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

A change to better support installs on UWP unfortunately introduced a merge issue for this PR. Please feel free to ping me to help work through any merge issues you encounter.

David

length += (ulong)(new FileInfo(item).Length + boundaryLength);
}
length += (ulong)(boundaryLength + 4);
return true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This method should return false in error scenarios or it should be renamed ComputeLength and throw on error.

/// </summary>
internal sealed class HttpMultipartFileContent : IHttpContent
{
private List<string> items = new List<string>();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Throughout, please add comment blocks similar to the other classes in the code :)

});
}

private async Task<ulong> WriteToStreamAsyncTask(IOutputStream outputStream, Action<ulong> progress)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Issue #228 will necessitate reworking this for the UWP version of WDPW.

/// <param name="requestStream">Optional stream containing data for the request body.</param>
/// <param name="requestStreamContentType">The type of that request body data.</param>
/// <returns>Task tracking the completion of the POST request</returns>
private async Task<Stream> PostAsync(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

does removing async here create any issues with calling code?

@microsoft microsoft deleted a comment from msftclas Sep 27, 2017
@hpsin hpsin added this to the 1.0 Release milestone Nov 10, 2017
@WilliamsJason
Copy link
Copy Markdown
Contributor

I'm going to close this PR since I pulled it into my Fork and have a new PR up with the same changes. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants