Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Build on change characteristics - when builds are not fast #691

Closed
alexheretic opened this issue Feb 1, 2018 · 6 comments
Closed

Build on change characteristics - when builds are not fast #691

alexheretic opened this issue Feb 1, 2018 · 6 comments

Comments

@alexheretic
Copy link
Member

RLS build logic reacts to didChange notifications by building immediately.

This isn't ideal because changes are soon followed by friends & the R in RLS stands for "Really slow compiling".

Let me demonstrate:

Here Rls handles a long compile time by doubling it and showing a meaningless error at half time. (The error you'd get from the first character typed).

Options

  • Change to simply debounce on didChange, in a non-eager way, using the wait_to_build duration.
  • Interact with rustc via a seperate process so it can be killed & replaced when a new request appears.

Hopefully that makes sense, any other ideas to improve this?

@nrc
Copy link
Member

nrc commented Feb 2, 2018

Change to simply debounce on didChange, in a non-eager way, using the wait_to_build duration.

We used to do this, there is a bit of a trade-off here - an initial wait means longer until the RLS has any info (consider a block delete), and longer if there is just a single change. OTOH, the current behaviour is not ideal as you observe. It is pretty easy to wait on the initial change, we should probably just give it a go and see how it feels.

Interact with rustc via a seperate process so it can be killed & replaced when a new request appears.

This is tricky since we need to pass changed (and not saved) files in memory which requires the same process (and we return save-analysis info in memory too). We could consider using some kind of RPC but I suspect that will be complex and might have significant performance overhead (the output especially can be significant and serialisation/deserialisation has been a significant part of profiles before we moved to a direct approach). In a future where we do this incrementally, it is probably worth investigating - being able to cancel build jobs would be really good.

@alexheretic
Copy link
Member Author

We used to do this, there is a bit of a trade-off here - an initial wait means longer until the RLS has any info (consider a block delete), and longer if there is just a single change. OTOH, the current behaviour is not ideal as you observe. It is pretty easy to wait on the initial change, we should probably just give it a go and see how it feels.

Yep the drawback of non-eager debounce is having to wait. This seems to be a problem mostly when the builds are fast and waiting ~500ms becomes a large part of the build time. We could be cleverer here, recording the last build duration and acting differently if it was slow. So if a build takes N * wait_to_build we switch to non-eager behaviour for future builds.

However, I can't help but think that cancelling builds is a capability that is very important in making Rls as responsive as it should be. That we can't actually puts us at a fairly large disadvantage compared to a naive linter calling/killing cargo check. For some users the fact that Rls can work on in-memory changes (which is great) may not be enough of a consolation.

I am aware that cancelling a thread is not something std currently supports. But I think we need a plan for cancelling builds somehow.

  • Step 1 (easy): Introduce cancelled build concept - avoid publishing diagnostics from a cancelled build
  • Step 2 (hard): Stop rustc building as soon as a build is cancelled.

Actually step 1 would at least avoid the invalidated error above 'expected item, found `/`'.

nrc added a commit that referenced this issue Feb 5, 2018
Wait for the timeout. Also makes the timeout a bit longer

cc #691
@nrc
Copy link
Member

nrc commented Feb 5, 2018

I pushed a commit which waits for the timeout before doing the initial build and also makes the timeout a bit longer. The added wait time didn't cause much difference to response time but didn't make a lot of difference to CPU utilisation either.

An alternate behaviour which would do less work (and cut out the intermediate results) would be to not build any normal priority builds until the user stops typing (i.e., until we get to a timeout without any new events. That would make it even slower to get help from the compiler, but should be much better for CPU utilisation - which people care about a lot more than I expected - and mean fewer false positive error messages.

@alexheretic
Copy link
Member Author

I'd expect it to behave like regular debounce, start a build Xms after the last build triggering event.

That way we can have a small wait duration (500-1000ms) as it just gets extended as more characters are typed.

@alexheretic
Copy link
Member Author

I'm not sure about the 1500 wait to build default. I think 500 was better, we should just avoid publishing outdated diagnostics.

bors added a commit that referenced this issue Jan 28, 2019
Bump rand from 0.6.4 to 0.6.5

Bumps [rand](https://github.com/rust-random/rand) from 0.6.4 to 0.6.5.
<details>
<summary>Changelog</summary>

*Sourced from [rand's changelog](https://github.com/rust-random/rand/blob/master/CHANGELOG.md).*

> ## [0.6.5] - 2019-01-28
> ### Crates
> - Update `rand_core` to 0.4 ([#703](https://github-redirect.dependabot.com/rust-random/rand/issues/703))
> - Move `JitterRng` to its own crate ([#685](https://github-redirect.dependabot.com/rust-random/rand/issues/685))
> - Add a warm-bindgen test crate ([#696](https://github-redirect.dependabot.com/rust-random/rand/issues/696))
>
> ### Platforms
> - Fuchsia: Replaced fuchsia-zircon with fuchsia-cprng
>
> ### Doc
> - Use RFC 1946 for doc links ([#691](https://github-redirect.dependabot.com/rust-random/rand/issues/691))
> - Fix some doc links and notes ([#711](https://github-redirect.dependabot.com/rust-random/rand/issues/711))
</details>
<details>
<summary>Commits</summary>

- [`a8dc9ad`](rust-random/rand@a8dc9ad) Merge pull request [#714](https://github-redirect.dependabot.com/rust-random/rand/issues/714) from dhardy/master
- [`625411c`](rust-random/rand@625411c) Update changelog for 0.6.5
- [`76acffe`](rust-random/rand@76acffe) Merge pull request [#712](https://github-redirect.dependabot.com/rust-random/rand/issues/712) from erickt/master
- [`351edce`](rust-random/rand@351edce) Merge pull request [#711](https://github-redirect.dependabot.com/rust-random/rand/issues/711) from dhardy/master
- [`1d0d26c`](rust-random/rand@1d0d26c) Bump version, and document fuchsia_cprng change
- [`9ffaeb7`](rust-random/rand@9ffaeb7) Add rustdoc logo/root link config to sub-crates
- [`ec13800`](rust-random/rand@ec13800) Travis: allow failure of Android test
- [`b22b637`](rust-random/rand@b22b637) Fix external links in SmallRng documentation
- [`6ce5f81`](rust-random/rand@6ce5f81) Add links to the crate pages for the rngs mentioned in StdRng docs
- [`8112daa`](rust-random/rand@8112daa) Merge pull request [#703](https://github-redirect.dependabot.com/rust-random/rand/issues/703) from dhardy/master
- Additional commits viewable in [compare view](rust-random/rand@0.6.4...0.6.5)
</details>
<br />

[![Dependabot compatibility score](https://api.dependabot.com/badges/compatibility_score?dependency-name=rand&package-manager=cargo&previous-version=0.6.4&new-version=0.6.5)](https://dependabot.com/compatibility-score.html?dependency-name=rand&package-manager=cargo&previous-version=0.6.4&new-version=0.6.5)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot ignore this [patch|minor|major] version` will close this PR and stop Dependabot creating any more for this minor/major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot badge me` will comment on this PR with code to add a "Dependabot enabled" badge to your readme

Additionally, you can set the following in the `.dependabot/config.yml` file in this repo:
- Update frequency (including time of day and day of week)
- Automerge options (never/patch/minor, and dev/runtime dependencies)
- Pull request limits (per update run and/or open at any time)
- Out-of-range updates (receive only lockfile updates, if desired)
- Security updates (receive only security updates, if desired)

Finally, you can contact us by mentioning @dependabot.

</details>
@Xanewok
Copy link
Member

Xanewok commented Mar 3, 2019

Cancellable build should be implemented with #1307 and @alexheretic implemented a dynamically inferred wait_for_build so this shouldn't be a problem now (feel free to reopen if that doesn't cover everything here).

@Xanewok Xanewok closed this as completed Mar 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants