Skip to content
This repository has been archived by the owner on Jul 30, 2018. It is now read-only.

Adding upload progress reporting, issue #285 #326

Merged
merged 7 commits into from
May 12, 2017

Conversation

rorticus
Copy link
Contributor

Type: feature

The following has been addressed in the PR:

  • There is a related issue
  • All code matches the style guide
  • Unit or Functional tests are included in the PR

Description:

Adds upload progress monitoring to the node & XHR request providers. It is implemented as a request option because by the time the returned promise is resolved, the uploads have already finished. Basic usage is,

const uploadObserver = new UploadObserver();
uploadObserver.on('upload', event => {
    console.log(`Total bytes uploaded: ${event.totalBytesUploaded}`);
});
request.get('http://www.example.com', {
    method: 'POST',
    body: aLotOfData,
    uploadObserver
});

XHR was easy as it emits upload events already. The node uploader was a bit more tricky, as there doesn't seem to be a way to find out how much data node has uploaded when using request.write. As such, I've added support for passing a readable stream to the node provider. As data is read from the stream, it is written to the request, and upload progress can be reported.

Resolves #285

@rorticus rorticus requested review from agubler and matt-gadd April 28, 2017 11:49
@rorticus
Copy link
Contributor Author

CI failures seem to be an unrelated issue 😄

@rorticus rorticus requested a review from kitsonk April 28, 2017 11:55
@codecov
Copy link

codecov bot commented Apr 28, 2017

Codecov Report

Merging #326 into master will increase coverage by 0.07%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #326      +/-   ##
==========================================
+ Coverage   93.97%   94.05%   +0.07%     
==========================================
  Files          39       40       +1     
  Lines        2142     2202      +60     
  Branches      407      408       +1     
==========================================
+ Hits         2013     2071      +58     
- Misses         51       52       +1     
- Partials       78       79       +1
Impacted Files Coverage Δ
src/request/Response.ts 78.57% <100%> (-0.74%) ⬇️
src/request/providers/xhr.ts 87.66% <100%> (+1.84%) ⬆️
src/request/SubscriptionPool.ts 100% <100%> (ø)
src/request.ts 96.87% <100%> (+0.72%) ⬆️
src/request/providers/node.ts 89.42% <100%> (+0.53%) ⬆️
src/QueuingEvented.ts 90.62% <0%> (-6.25%) ⬇️

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 b4492c3...57e3335. Read the comment docs.

Copy link
Member

@dylans dylans left a comment

Choose a reason for hiding this comment

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

one minor nit from me, this looks reasonable though I'm sure someone else should also review this.

docs/request.md Outdated
});
```

Note that while the node provider will emit a single `upload` event when it is done uploading, it cannot emit more granular upload events with `string` or `Buffer` body types. To receive more frequent upload events, you can use the `bodyStream` option to provide a `Readable` with the body content. Upload events will be emitted as the data is read from the stream.
Copy link
Member

Choose a reason for hiding this comment

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

node -> Node.js

@dylans dylans modified the milestones: 2017.04, 2017.05 Apr 29, 2017
Copy link
Member

@kitsonk kitsonk left a comment

Choose a reason for hiding this comment

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

A few comments.

@@ -35,6 +35,16 @@ const request: {
});
});

[ 'POST', 'PUT' ].forEach(method => {
Object.defineProperty(request, method.toLowerCase(), {
value(url: string, options: RequestOptions = {}): UploadObservableTask<Response> {
Copy link
Member

Choose a reason for hiding this comment

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

We don't have a test for request options default to nothing, therefore we are missing a branch in our testing.

this._observers.push(subscription);

return () => {
this._observers.splice(this._observers.indexOf(subscription), 1);
Copy link
Member

Choose a reason for hiding this comment

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

Not being covered in the tests.

}

complete() {
this._observers.forEach(observer => {
Copy link
Member

Choose a reason for hiding this comment

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

Not covered in testing.

Copy link
Member

Choose a reason for hiding this comment

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

Fixed now

import Response from '../Response';
import TimeoutError from '../TimeoutError';
import { Readable } from 'stream';
import { UploadObserverEvent } from '../interfaces';
import Observable from '../../Observable';
Copy link
Member

Choose a reason for hiding this comment

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

Codecov says this file isn't covered at all.

value(url: string, options: RequestOptions = {}): UploadObservableTask<Response> {
options = Object.create(options);
options.method = method;
return <UploadObservableTask<Response>> request(url, options);
Copy link
Member

Choose a reason for hiding this comment

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

While it isn't a big deal, we are trying to move to return request(url, options) as UploadObservableTask<Response>; The TypeScript team is recommending it to avoid issues with JSX. Though we don't plan to use JSX, it still feels cleaner/more readable.

@rorticus rorticus force-pushed the issue-285 branch 2 times, most recently from edd9752 to b6749ed Compare May 5, 2017 14:27
@rorticus
Copy link
Contributor Author

rorticus commented May 5, 2017

@dylans Updated to use Node.js 👍

@rorticus
Copy link
Contributor Author

rorticus commented May 5, 2017

@kitsonk OK, I've refactored to use Observables for everything. See the README for details, but basically Request exposes upload and Response exposes download and data.

}

complete() {
this._observers.forEach(observer => {
Copy link
Member

Choose a reason for hiding this comment

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

Fixed now


// when the queue is full, get rid of the first ones
while (this._queue.length > this._queueMaxLength) {
this._queue.shift();
Copy link
Member

Choose a reason for hiding this comment

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

Not covered in testing.

Copy link
Member

@kitsonk kitsonk left a comment

Choose a reason for hiding this comment

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

We should cover the missing line and branches.

@rorticus
Copy link
Contributor Author

@kitsonk Added a few more tests for better coverage

Copy link
Member

@dylans dylans left a comment

Choose a reason for hiding this comment

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

My feedback has been addressed... obviously Kit needs to verify that his feedback has as well before this is landed.

@rorticus
Copy link
Contributor Author

We might be able to get rid of QueuingEvented, but I'm not sure if anyone is using it... It's no longer being used in core but it looks like it's been modified since creation, so I just left it alone.

@kitsonk
Copy link
Member

kitsonk commented May 12, 2017

The only thing I am missing is the full coverage on this line. If it isn't testable, then we don't need the default argument.

@rorticus
Copy link
Contributor Author

@kitsonk That line should be covered now!

Copy link
Member

@kitsonk kitsonk left a comment

Choose a reason for hiding this comment

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

Happy camper now! 😂 ⛺️

@rorticus rorticus merged commit a51adb2 into dojo:master May 12, 2017
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.

Add upload progress reporting
3 participants