fix: stale live reload due to dropped watch events #649
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
While working on docs.deno.com we noticed that the page shown in the browser would often go out of sync with the actual content on disk. Debugging this further lead two a discovery of two separate bugs in the watcher + live reloading code.
When you edit a file and hit save while a previous change is still being processed it would be dropped here:
lume/core/watcher.ts
Lines 87 to 89 in abefe9f
This lead to generated files lagging behind one or potentially more changes depending on how many watch events were dropped. I've resolved this by adding a queue of events that is processed in order. To avoid processing the same file more often than necessary there is a small optimisation that merges queued events if they are the same.
But with this fix in place the browser was still showing a previous version of the page. Turns out that we frequently run into the situation where a watch event is received, whilst the browser is disconnected and is in the process of being reloaded due to an earlier change. These events were dropped here:
lume/middlewares/reload.ts
Lines 16 to 19 in abefe9f
To resolve this, I've added a simple "revision" tracking mechanism. When a new connection is opened the server immediately sends the current revision to the browser so that it can check if it has become stale and potentially reload the page. The initial revision is included in the HTML and passed to the
liveReload()
function as an argument.Before
Notice how even refreshing the browser shows the stale version.
lume-watch-before.mp4
After
Notice how the changes are all sent to the browser and it has the correct state even if you reload it. It seems like during processing the lume server is blocked from responding to the browser, otherwise the intermediate states would also be shown in it.
lume-watch-after.mp4
Related Issues
Check List
CODE OF CONDUCT
CONTRIBUTING
send multiple pull request.
fmt
to fix the code format before commit.CHANGELOG.md
.