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

DevTools: Add version to protocol used between backend/frontend #21326

Closed
2 tasks done
bvaughn opened this issue Apr 21, 2021 · 4 comments
Closed
2 tasks done

DevTools: Add version to protocol used between backend/frontend #21326

bvaughn opened this issue Apr 21, 2021 · 4 comments

Comments

@bvaughn
Copy link
Contributor

bvaughn commented Apr 21, 2021

The problem

DevTools packages are published to NPM and follow semver for their public APIs (e.g. connectToDevTools from react-devtools-core). However the protocol used to communicate between the "backend" and "frontend" components is unversioned and may change between releases. Normally this does not cause a problem as the browser extensions, react-devtools-inline package, and react-devtools standalone package (used for browsers like Safari) all bundle these components together (e.g. the frontend injects or serves via an embedded web server the backend script so there's a 1:1 match).

However, React Native poses a special challenge. The React Native renderer embeds the "backend" component within renderer itself (in DEV mode), but the user launches the "frontend" UI via NPM or a tool like Flipper or the React Native Debugger. In either case, there is no guarantee that the version of the "frontend" UI will match the version of the embedded "backend". (React Native does specify a react-devtools-core dependency but users are often running a globally installed version of the React DevTools or Flipper and so nothing even checks the dependency version.)

This means that updates to React Native (or more specifically, updates to the embedded DevTools backend) can cause DevTools installations to stop working without an apparent reason or an obvious solution.

The plan

The long term plan going forward (as implemented in #21331) is:

  1. Add an explicit version to the protocol used by the DevTools "backend" and "frontend" components to talk to each other.
  2. Check this protocol during initialization to ensure it matches.
  3. Show upgrade/downgrade instructions if there's a mismatch (or if the check times out without a response– indicating an older backend).
  4. Release this as 4.13.

The short term plan (as implemented in #21344) is:

  1. Branch and make a patch release of DevTools 4.10 that adds a protocol check to the frontend (to detect any newer backends).
  2. Upgrade Flipper (and recommend upgrade for the OSS React Native Debugger as well) to this new frontend.
  3. Wait a week or so for rollout and then upgrade React Native to the 4.13 backend.

Based on my not-very-scientific poll it seems like people mostly use DevTools via NPM, but Flipper and React Native Debugger have a pretty big user share too. The upgrade/downgrade instructions will then be geared primarily to NPM users but with an FBURL that links to a Gist with instructions for these other tools as well.

Checklist

@bvaughn
Copy link
Contributor Author

bvaughn commented Apr 21, 2021

Here is my proposal:

  • Release version 4.13.0 with:
    • Add a new message sent from the frontend to the embedded backend to check the protocol version.
    • Update the frontend to check for the new protocol version and show a message in the UI if it doesn't match or if the backend doesn't respond (because it doesn't yet support this new message type).
  • Release version 4.10.x with:
    • Update the frontend to check for the new protocol version and show a message in the UI if any version is found. (Any version at all means the frontend will be newer than 4.10+ so we'll know to prompt the user to upgrade.)

backend frontend expected behavior
4.10.x 4.10.x Send "getProtocolVersion". Timeout after no response. Assume compatibility.
4.10.x 4.13+ Send "getProtocolVersion". Timeout after no response. Show downgrade dialog.
4.13+ 4.10.x Send "getProtocolVersion". Get response. Show NPM upgrade dialog.
4.13+ 4.13+ Send "getProtocolVersion". Verify compatibility with response.

Put another way, there are three cases we'll need to handle:

  • New frontend with pre-version backend:
    • In this case, the frontend can just recommend NPM 4.10.1 as a best guess for a frontend version that would work with an older backend.
  • New frontend with older protocol version backend:
    • Frontend can maintain a mapping of protocol versions to min/max NPM version ranges and can use the older backend version to recommend a frontend version range.
  • Old frontend with newer protocol version backend:
    • Frontend won't know about this protocol version yet, but backend can return the NPM version in which it was added and the frontend can suggest updating to that version or later.

@bvaughn
Copy link
Contributor Author

bvaughn commented Apr 21, 2021

I think ideally for Flipper and RN, React DevTools frontend would just support all backwards version of the backend protocol (kind of like it supports all recent React versions) but I don't think this is feasible for me to maintain. (Also the ship has already sailed with past releases that did not specify a protocol version.)

Even if that was not the case, I think frontend updates to things like inspecting element props and state (which use new React Suspense APIs) would just be too complicated to manage if I had to support multiple protocol versions.

In terms of managing that kind of complexity going forward, one theoretical option would be to somehow bundle multiple versions of the frontend into each NPM release and then dynamically load them based on the backend version, but I think this would also be a big lift and maybe isn't the most pragmatic solution.

@bvaughn bvaughn self-assigned this Apr 21, 2021
@bvaughn
Copy link
Contributor Author

bvaughn commented Apr 22, 2021

e.g. backend requires a newer protocol than the frontend supports

backend requires a newer protocol than the frontend supports

e.g. backend requires a older protocol than the frontend supports

backend requires a older protocol than the frontend supports

facebook-github-bot pushed a commit to facebook/flipper that referenced this issue Apr 27, 2021
Summary:
Bumps [react-devtools-core](https://github.com/facebook/react/tree/master/packages/react-devtools-core) from 4.10.1 to 4.10.2.

This update has only one change: facebook/react#21344

For more background information on this upgrade: facebook/react#21326

cc mweststrate

Pull Request resolved: #2243

Reviewed By: bvaughn

Differential Revision: D28040682

Pulled By: mweststrate

fbshipit-source-id: 82b1212f839719ff69b3b7735a8a24042b382085
@bvaughn
Copy link
Contributor Author

bvaughn commented Apr 28, 2021

I think this is done! The protocol check will release in 4.13 (soon).

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

No branches or pull requests

1 participant