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

feat: Overhaul Hot Reloads #86

Merged
merged 3 commits into from
Dec 23, 2021
Merged

Conversation

betterengineering
Copy link
Contributor

Overview

Nothing is worse than a hot reload that doesn't hot reload. As a user, I then no longer know if the update didn't work or my code is wrong. Before this change, we had two classes of issues where reload would fail: issues with detecting file changes and issues actually reloading.

This change really buttons up a lot of the issues with hot reloading to make it significantly more reliable. In addition, it maintains all of the current behavior around --watch, serve flags, and config through query params.

Features

  • WebP's are now sent over a websocket directly to the browser
    • Before, we simply forced the page to refresh when there was a change, which was significantly slower then just updating the WebP on the page.
  • Prettier web view
    • This change adds a preview mask to get the pixels, a Favicon, and a title to the page.
  • If the connection to the server dies, the page clears.
    • There are no more guessing games if we're actually connected and receiving updates.
  • Windows with refresh that lose a connection try to get it back over an exponential backoff
    • That way, an old browser tab will fix itself when the server comes back online
  • File watching now happens reliably and exactly once for a save through VIM or VSCode
    • We now watch the directory and only act on the events for the file we care about. Editors do weird stuff here that make it complicated to watch just one file. For example, VIM writes to a swap file and recreates the original file on save - which means we can't watch just that file.
  • The server dies if there are issues with the file watcher
    • This makes it really clear as a user that things are no longer reloading and you have to start up the server again, especially given the browser page dies as well when the connection is lost.
  • Mutexs were replaced with channels
    • This makes everything a lot snappier. Go routines should work together by communicating and not by sharing.

Changes

  • Added new server packages.
    • This commit open sources a few modules that were internal to Tidbyt and refactors existing server code into a loader and watcher module. Some big changes in the refactor include directory watching inside of watcher to ensure we get every update and removing sync.Mutex in favor of channels.
  • Refactored server to use new packages.
    • This commit refactors the server code to use our new packages.

Future Work

  • Config through query parameters is set via the last time the page was refreshed and not per page. This means setting config in one window will cause an incorrect update in another window.
    • I started making a change to do this as part of this one, but I realized it's going to be a decently large change and a few hours of effort to really get right. We need to map config -> fanout so that a config update pushes updates to all windows with that config. It also means if the file is changed, we need a map of config -> update channels and render the app multiple times to ensure everything is updated.
  • LoadApplet makes me feel bad 😄 . It shouldn't work that way and needs to be cleaned up.

Preview

pixlet-final.mov

This commit open sources a few modules that were internal to Tidbyt and
refactors existing server code into a loader and watcher module. Some
big changes in the refactor include directory watching inside of watcher
to ensure we get every update and removing sync.Mutex in favor of
channels.
This commit refactors the server code to use our new packages.
@betterengineering
Copy link
Contributor Author

betterengineering commented Dec 23, 2021

Looks like i'll need to update the build agents to go1.16 to get file embedding to work.

This commit updates the test actions to use go 1.16.12 to match the
go.mod and to be able to support go embpedding.
@betterengineering
Copy link
Contributor Author

Double checked, this also works with a remote host in VSCode with port forwarding 🤓

@betterengineering betterengineering merged commit ce90198 into main Dec 23, 2021
@betterengineering betterengineering deleted the mark/overhaul-hot-reloads branch December 23, 2021 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant