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

Faster REPL - don't load extra middleware on first sync eval request #2078

Merged
merged 3 commits into from
Oct 1, 2017

Conversation

vspinu
Copy link
Contributor

@vspinu vspinu commented Aug 22, 2017

This saves a couple of extra seconds and brings cider repl startup time to barebones empty-project lein repl of 4s for me.


  • Send :inhibit-cider-middleware condition on first request. Relies on a feature added in Dynamically load middleware cider-nrepl#438.

  • Combine require-repl-utils and set-initial-ns into one sync request for efficiency. Note that require-repl-utils needs to be a sync request. It could happen that the following init-debuger request would occur before it has finished, resulting in "reader/reader not found error".

@vspinu
Copy link
Contributor Author

vspinu commented Aug 24, 2017

From #2081:

I was just wondering whether to try to include there some of @vspinu's performance improvement patches or push those back to 0.16.

It depends how long would it take to release 0.16. I would like to see #2069 in 0.16 and that change with associated features/fixes might take quite some months. If we can pull it in within a couple of months then this change can also go in 0.16, if not then it might be better included now.

As noted in 721440b, there is one side effect of dynamic loading of middlware - it can occur concurrently. But Clojure seems to have trouble loading namespaces in parallel.

I haven't investigated this thoroughly but I run into issues when debug middleware was requested before out middleware in async requests. As debug is heavy, out middleware ends up loaded simultaneously with debug and didn't load correctly. This is why I changed the order of those two requests on emacs side. out middleware is very light and doesn't cause issues with the debug.

Fixing this on cider's side is easy, just implement a kind of deffered chain to load cider's middleware. But then, some other packages (nrepl-refactor?) might load same namespaces in parallel. One partial solution is to run cider-connected-hook at the end of the deffered chain and request external packages to rely on cider-connected-hook (which they should do anyways).

@xiongtx
Copy link
Member

xiongtx commented Aug 24, 2017

But Clojure seems to have trouble loading namespaces in parallel.

Is this due to dependencies between namespaces? Needs a topological sort?

@vspinu
Copy link
Contributor Author

vspinu commented Aug 24, 2017

Is this due to dependencies between namespaces? Needs a topological sort?

No. It's just that if two actions simultaneously try to load same namespace, something goes wrong and one of them is not loaded correctly.

@xiongtx
Copy link
Member

xiongtx commented Aug 24, 2017

Can you put up a minimal repo that reproduces this problem? Seems like a Clojure level issue, not cider-nrepl.

@vspinu
Copy link
Contributor Author

vspinu commented Aug 24, 2017

Yes, it's a Clojure level issue. If I had a minimal rep. example I would have had already reported it on JIRA.

@bbatsov
Copy link
Member

bbatsov commented Aug 25, 2017

As noted in 721440b, there is one side effect of dynamic loading of middlware - it can occur concurrently. But Clojure seems to have trouble loading namespaces in parallel.

Things like these are generally my concern - don't like introducing potentially breaking changes in a bugfix release.

It depends how long would it take to release 0.16. I would like to see #2069 in 0.16 and that change with associated features/fixes might take quite some months. If we can pull it in within a couple of months then this change can also go in 0.16, if not then it might be better included now.

There's never a precise roadmap for releases. Generally I cut them when I feel we've added something important enough to warrant a release.

cider-repl.el Outdated
"Set the REPL BUFFER's initial namespace (by altering `cider-buffer-ns').
This is \"user\" by default but can be overridden in apps like lein (:init-ns)."
(defun cider-repl-require-repl-utils-and-set-ns (buffer)
"Require standard REPL util functions and set the REPL BUFFER NS.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NS -> ns (it's not a param).

cider-repl.el Outdated
This is \"user\" by default but can be overridden in apps like lein (:init-ns)."
(defun cider-repl-require-repl-utils-and-set-ns (buffer)
"Require standard REPL util functions and set the REPL BUFFER NS.
Namespace is \"user\" by default but can be overridden in apps like
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default, but

cider-repl.el Outdated
(defun cider-repl-require-repl-utils-and-set-ns (buffer)
"Require standard REPL util functions and set the REPL BUFFER NS.
Namespace is \"user\" by default but can be overridden in apps like
lein (:init-ns). Booth of these operations need to be done as a sync
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

booth -> both

cider-repl.el Outdated
"Require standard REPL util functions and set the REPL BUFFER NS.
Namespace is \"user\" by default but can be overridden in apps like
lein (:init-ns). Booth of these operations need to be done as a sync
request at the beginning of the session. Bundling them for efficiency."
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's one space missing here before the final sentence.
them -> them together

(when cider-repl-display-in-current-window
(add-to-list 'same-window-buffer-names (buffer-name buffer)))
(pcase cider-repl-pop-to-buffer-on-connect
(`display-only (display-buffer buffer))
((pred identity) (pop-to-buffer buffer)))
(cider-repl-require-repl-utils-and-set-ns buffer)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you move those down?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The REPL shows a bit earlier (.5-1 sec for me). Also, the repl is always shown, even when errors occur with those subsequent requests.

cider.el Outdated
(cider--subscribe-repl-to-server-out)
(when cider-auto-mode
(cider-enable-on-existing-clojure-buffers))
;; Middleware on cider-nrepl side is loaded dynamically on first
;; usage. Loading middleware concurrently can lead to confusing issues
;; (likely a clojure bug). Debug middleware is heavy, so enable it at the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recall you verified this is a bug, so I think you should mention it here. The next sentence doesn't sound very reassuring. 😃

@bbatsov
Copy link
Member

bbatsov commented Sep 16, 2017

I guess you can also add to this PR a changelog entry, as users are going to be quite excited about the speedup.

@bbatsov
Copy link
Member

bbatsov commented Sep 27, 2017

@vspinu ping :-)

@vspinu
Copy link
Contributor Author

vspinu commented Sep 27, 2017

Sorry for being slow on this. My kid was just born a couple of weeks ago, so my bandwidth is 1/10th of what it was before :) Will try to fix all my PRs by Saturday.

@bbatsov
Copy link
Member

bbatsov commented Sep 27, 2017

Sorry for being slow on this. My kid was just born a couple of weeks ago, so my bandwidth is 1/10th of what it was before :) Will try to fix all my PRs by Saturday.

Thanks and congratulations! 🎉 🎂

@vspinu vspinu force-pushed the faster-repl branch 2 times, most recently from 5dbdf2f to 4b4aa08 Compare September 30, 2017 20:06
  - Sending :inhibit-cider-middleware condition on first request

  - Combining require-repl-utils and set-initial-ns into one sync request for
    efficiency
@vspinu
Copy link
Contributor Author

vspinu commented Sep 30, 2017

@bbatsov, I have addressed your comments in all of my PRs (also the one on cider-nrepl side). Added all change-log entries here to avoid conflicts.

@bbatsov bbatsov merged commit 46367ce into clojure-emacs:master Oct 1, 2017
@bbatsov
Copy link
Member

bbatsov commented Oct 1, 2017

👍

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.

3 participants