Skip to content
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

refactor: the async await extravaganza #811

Merged
merged 20 commits into from
Oct 5, 2020
Merged

Conversation

lidel
Copy link
Member

@lidel lidel commented Nov 7, 2019

This PR:

TODO

  • switch to new way of customizing libp2p bundle in brave
  • switch companion codebase to new API
    • quick import in Firefox

    • quick import in Chromium

      • broken by additional serialization that was not present in Firefox
        refs: https://bugs.chromium.org/p/chromium/issues/detail?id=112163, potential fix via trampoline from https://stackoverflow.com/a/21101597/11518426, https://stackoverflow.com/a/24303394/11518426
      • There is a discrepancy between how objects are passed between a page and background page within the same extension in Firefox and Chromium.
      • It seems that ReadableStream produced by file.stream() is able to correctly pass the boundary between quick import page and the IPFS API object running in the background.
      • Did some tests to see how big is the difference, to decide if its worth special-casing http client when external node is used, results below:
      • 4GB import test Firefox
        • file.stream() + bg-page http client → ~47s
        • file.stream() + same-page http client → ~47s
        • file (Blob) + same-page http client → ~25s 💚
        • file.stream() + bg-page js-ipfs → ~1m40s
      • 4GB import test Chromium
        • file.stream() + bg-page http client → 💔 always errors after ~15s
        • file.stream() + same-page http client → 💔 always errors after ~15s
        • file (Blob) + same-page http client → ~25s 💚
        • file.stream() + bg-page js-ipfs → ~1m30s
      • tl;dr file (Blob) + same-page http client provide best performance for external node, while file.stream() + bg-page js-ipfs make things work okay-ish when embedded js-ipfs is used (we don't expect people to import 4GB with embedded node so good for now)
    • fix progress reporting

      • for now only works with embedded node, but as soon its fixed in http client it will start working there too:

        2020-09-24--02-04-53

    • precache

    • context actions

    • import via context action -- seee Backwards compatibility of ipfs.add(urlSource(url)) js-ipfs#3195 first

    • embedded js-ipfs in Chrome

    • embedded js-ipfs in Brave

  • switch Brave to webrtc (and stardust?)

@lidel
Copy link
Member Author

lidel commented Dec 4, 2019

@alanshaw i don't think ipfs/js-ipfs#2591 landed in v0.40.0, it will land in next release, right?

@alanshaw
Copy link
Member

alanshaw commented Dec 4, 2019

Yep!

@lidel lidel changed the title refactor: DRY way of customizing libp2p bundle refactor: The Async Await Extravaganza Apr 24, 2020
@lidel lidel force-pushed the refactor/dry-libp2p-config branch from 7132542 to 8d2ff1d Compare April 25, 2020 01:03
@lidel
Copy link
Member Author

lidel commented Apr 25, 2020

Need to switch to latest js-ipfs, so I am repurposing this PR for general async iterators refactor, context #843

This is WIP.

Switches JS API to async iterators where possible.

Includes switch to libp2p config override via  ipfs/js-ipfs#2591

BREAKING CHANGE: switched to Async Iterators version of JS API
https://blog.ipfs.io/2020-02-01-async-await-refactor/
- the latest js-ipfs builds and runs in the browser
- 4x delegates and preloads enabled
- 2x webrtc star provides signaling

Known Issues:

- the node starts, but struggles to find content, and there is a separate
  issue of infinite restart when user enables and disables it too fast
- import via quick import page fails due to API discrepancy
@lidel lidel force-pushed the refactor/dry-libp2p-config branch from 3fadffa to 4dda1b1 Compare August 18, 2020 13:51
As usual, additional hackery was required to get hapijs work in Chrome
Apps context. There seem to be an import bug in js-ipfs when using the
latest ipfs-webui, so we stay at the old version for now (for Brave
only)
modern js-ipfs is using it for timeouts
web-ext lint requires JS files to be under 4MB, and latest js-ipfs
included more dependencies, so we moved some of them from
"backgroundBundle" to "ipfs" one, making it under 4MB.
Chrome seems to be broken by additional serialization that occurs.
Potential fix may be just getting API address and creating new instance
of http-client in quick-import.html (that will remove cross-process
boundary in Chromium)
In short, there is a discrepancy between how objects are passed between
a page and background page within the same extension in Firefox and
Chromium.

Quick import in Chromium was broken, most likely by additional process
boundary serialization that was not present in Firefox, could be related
to upstream bug at:
https://bugs.chromium.org/p/chromium/issues/detail?id=112163

Potential fix via trampoline from https://stackoverflow.com/a/21101597/11518426
is too brittle, as Chromium can break it in browser context at any time.

It seems that ReadableStream produced by file.stream() is able to
correctly pass the boundary between quick import page and the IPFS API
object running in the background, so we use it with embedded js-ipfs,
but for external node we use http client directly from quick upload
page, and pass File object as-is, which takes 1/2 of time.

Additional benchmarks can be found in
#811
for now just embedded js-ipfs, but http-client will be fixed in one of
future releases and will benefit from this as well
js-ipfs in brave does not work correctly and we can't update to the
latest one because of other issues.

embedded js-ipfs in brave goes away in next year, so we simply open
imports on gateway when chrome apps runtime is used, which is good
enough for experimental feature
embedded node in brave does not need it anymore, we reload entire
extension on port change

regular embedded never needed it
this enables webrtc-based signaling and delegates for experimental
js-ipfs running in extension context (non-Brave) when no custom config
is provided
@lidel lidel force-pushed the refactor/dry-libp2p-config branch from 2236ecf to 18ebc75 Compare October 5, 2020 19:46
@lidel lidel marked this pull request as ready for review October 5, 2020 20:04
We were bundling TAR inside of Chromium package to make it work
instantly when opened in Brave.

Unfortunately it added 10MB to the package, which meant one-click
install was slow in Brave, but also on every other Chromium browser.

This replaces bundled TAR with prefetching it from a public gateway on
the first run. The idea is that if user had access to Chrome Web Store
to install extension, they have access to the gateway, so no need for
bundling.

We also precache regular webui in Chromium and Firefox via ipfs.refs
@lidel lidel force-pushed the refactor/dry-libp2p-config branch from 18ebc75 to ed319fa Compare October 5, 2020 20:12
@lidel
Copy link
Member Author

lidel commented Oct 5, 2020

Alright, this is as ready as it will be.

There are no functional changes, just refactor that accounts for new APIs + small bugfixes that I was able to applie while doing this.

Merging to unblock #921 and #888

@lidel lidel changed the title refactor: The Async Await Extravaganza refactor: the async await extravaganza Oct 5, 2020
@lidel lidel merged commit 1ebf389 into master Oct 5, 2020
@lidel lidel deleted the refactor/dry-libp2p-config branch October 5, 2020 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P0 Critical: Tackled by core team ASAP status/in-progress In progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migration to JS API with Async Await and Async Iterables
2 participants