-
Notifications
You must be signed in to change notification settings - Fork 262
LargeFileUpload task #584
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
LargeFileUpload task #584
Conversation
Avoid extra memory allocation when doing chunked upload for large file
- Wraps the chunkedUploadProvider in another LargeFileUpload - Prevents breaking changes by keeping obsolete method - Performance tests done
MIchaelMainer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to review a bit more.
|
|
||
| if (result.UploadSucceeded) | ||
| { | ||
| progressCallback?.OnSuccess(result.ItemResponse);// update the caller with sucess |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
| /// <param name="request">The UploadChunkRequest to make the request with.</param> | ||
| /// <param name="exceptionTrackingList">A list of exceptions to use to track progress. ChunkedUpload may retry.</param> | ||
| /// <returns></returns> | ||
| public virtual async Task<UploadChunkResult> GetChunkRequestResponseAsync(UploadChunkRequest request, ICollection<Exception> exceptionTrackingList) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this may be better called UploadChunkAsync().
| namespace Microsoft.Graph | ||
| { | ||
| /// <summary> | ||
| /// Interface for to enbale handling of progress/errors for a long upload process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo.
Additionally, we should make this generic enough to be used in other progress scenarios. This should be applicable to upload, download, or any other scenario where progress needs to be captured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.NET has an interface built in https://docs.microsoft.com/en-us/dotnet/api/system.iprogress-1?view=netframework-4.8
| /// Handler for scenario when process completes successfully | ||
| /// </summary> | ||
| /// <param name="result">The resulting file from the upload.</param> | ||
| void OnSuccess(DriveItem result); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to return a DriveItem? Could we make this some sort of result object? I'd like us to be reuse interface for other progress scenarios.
|
99% of this code should be in Core. We need to make this generic so that it is not tied to DriveItem. We will want to use this code for large attachment uploads also. |
|
We cannot use the term Chunk anywhere in our interface or samples. This is not chunking. |
| /// <param name="readBuffer">The byte[] content to read from.</param> | ||
| /// <param name="exceptionTrackingList">A list of exceptions to use to track progress. ChunkedUpload may retry.</param> | ||
| /// <returns></returns> | ||
| [Obsolete("This overload is obsolete. Please use the overload that does not use the unnecessary a readBuffer parameter")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's worth informing our customers that the readBuffer value passed here will be ignored.
| /// <param name="progressCallback"><see cref="IProgressCallback"/> object to monitor the progress of the upload.</param> | ||
| /// <returns>Item information returned by server.</returns> | ||
| public async Task<DriveItem> UploadAsync(int maxTries = 3, IEnumerable<Option> options = null) | ||
| public async Task<DriveItem> UploadAsync(int maxTries = 3, IEnumerable<Option> options = null , IProgressCallback progressCallback = null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @darrelmiller noted, lets consider using .Net's IProgress interface here.
|
|
||
| await this.UpdateSessionStatusAsync().ConfigureAwait(false); | ||
| uploadTries += 1; | ||
| if (uploadTries < maxTries) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This retry logic will result in 3^3 retries (by default) for 429, 503 and 504 HTTP responses when the service doesn't return a successful result. The underlying HTTP client already has a RetryHandler that handles retries for 429, 503 and 504 responses.
I'm waiting for a large file upload while sending emails. It was announced some time ago (https://docs.microsoft.com/en-us/graph/outlook-large-attachments?tabs=http), but its still unsupported here and in beta lib. |
|
Thanks for all the feedback on this PR. |
Changes proposed in this pull request
This work is done in accordance with the spec found at this link. https://github.com/microsoftgraph/msgraph-sdk-design/blob/master/tasks/FileUploadTask.md
Essentially, one may perform a large upload by following the steps below.
Alternatively, one may choose to do the file upload in slices by themselves by replacing step 3 and 4 with
Notes
One can find a sample app built upon this PR(using this repo as a git submodule) to showcase and test the above usage at the following link.
https://github.com/andrueastman/UploadFileSample