-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: report ipfs.add progress over http #3310
Conversation
I have bumped go-ipfs dependency to 0.7 to fix test failures caused by ipfs/go-ipfs-cmds#201, but it appears that 0.7 causes some other tests to fail, so I might have to create a separate PR that makes a update to 0.7 and fixes all those tests. |
Master has [email protected] now so if you merge that into this branch you should be able to rule that out as a source of failure. The core emits progress based on chunks of the file consumed, not including metadata as we want to avoid the situation where you upload 100b and get notifications up to 110b (or whatever). From what I understand, using the onProgress event of an XmlHttpRequestUpload would be the same - that is the payload is the file and the progress reported does not include bytes that are not the file (e.g. headers, etc) - or have I got that wrong?
This is harder as you'd have to know the size of the thing(s) you are uploading in advance which you might not depending on input. Better to let the user calculate percentages if it's important to them. |
🤔 So I am guessing that browsers don't count headers but they do count the form-data stuff, but I could be wrong. If that is the case, I could leverage |
Just verified that XHR Another alternative could be to just have separate progress reporting mechanism e.g. Passing @achingbrain could you please let me know which way do you want to go here, before I go about making them ? So I think this leaves us with two optinos |
Correction: I misunderstood what I have decided to implement progress reporting (in browsers) by interpolating it from upload events. In the process I realized that |
Last remaining failures seem to be caused by the ipfs-http-server doing strict origin checks that ipfs/go-ipfs-cmds#201 loosened up. |
js-ipfs has the same fix as ipfs/go-ipfs-cmds#201 in master now so this should be unblocked. Lots of conflicts though. |
To maintain compatibility with go-ipfs it's Also, it It would be better if there was more metadata returned with the progress event - the path of the file within the DAG being created at a minimum. You should be able to work it out though, and we could shim this into the http client without having to change go-ipfs if you don't fancy opening a PR, in that over http all files are added sequentially so you could keep track of where you are in the file stream to return the path/filename along with the chunk. To make js core do the same thing we can just |
A couple of clarifications on the last comment:
See the (new) tests: https://github.com/ipfs/js-ipfs/blob/master/packages/interface-ipfs-core/src/add.js#L117-L145 |
Could you rebase this please? Also, I'm a little wary here as: a) It makes the behaviour of the http client diverge from core |
Thinking about this a bit more, I think it's possible to retain compatibility with core, if we accept that the progress will only be mostly accurate. In the browser we have to consume the input stream for files in its entirety before starting the request in order to create the FormData object, while doing that we can keep a tally of file names and sizes. When ipfs/js-ipfs-utils#60 lands, it'll give us the total bytes transferred for the whole request. Because the files are uploaded serially the progress events should be received serially as well. Armed with that knowledge we can translate the total bytes transferred into progress through individual files and pass the same arguments to the progress callback function option as core does. Of course the total bytes transferred will include multipart headers etc so we either add a little overhead to each file size and account for that in the progress callback arguments, or just let the final progress callback invocation occur a short amount of time before it's actually finished. That should tide us over until #3371 lands and gives us proper streaming everywhere. |
6050c6f
to
71ce1d5
Compare
71ce1d5
to
fb4b147
Compare
@achingbrain I have updated the pull to derive progress for individual part based on total progress. |
Turns out there is one more problem, namely it appears that no progress events are emitted for directories as per tests here js-ipfs/packages/interface-ipfs-core/src/add-all.js Lines 145 to 169 in cea7317
While my implementation in this pull request was ensuring that progress events were fired for dirs. I will change implementation to omit dirs, however I wanted to call this out because this is yet another WTF in the way we report progress. |
Shipped in |
The browser fetch api doesn't allow reading of any data until the whole request has been sent which means progress events only fire after the upload is complete which rather defeats the purpose of reporting upload progress. Here we switch to XHR for uploads with progress that does allow reading response data before the request is complete. Co-authored-by: achingbrain <[email protected]>
This change integrates changes from ipfs/js-ipfs-utils#60. Once ipfs-utlis with changes are released I'll update dependencies so they don't point to the branch.
I think electron-renderrer tests are fail due to https://github.com/ipfs/go-ipfs-cmds/pull/201/files
@achingbrain this changes what numbers are passed to optional
progress
handler when callingadd
oraddAll
, specifically on http client numbers would reflect request payload size and not the file(s) size. Alternative could be to report percentage instead. Let me know what do you thing makes more sense here. In terms of using this in webui reporting percentage makes more sense, because otherwise we end up calculating total size + estimated metadata and the derive percentage from that.