CLJS-358, REPL environments and shared global state

55 views
Skip to first unread message

Chas Emerick

unread,
Jan 25, 2013, 6:01:39 PM1/25/13
to cloju...@googlegroups.com
I finally (not that I was working on it too hard) found the root cause of http://dev.clojure.org/jira/browse/CLJS-358: there's some shared state used by each flavour of REPL environment:

Rhino: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl/rhino.clj#L19
Browser-REPL: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/repl/browser.clj#L18

Specifically related to CLJS-358 is the `loaded-libs` set used by the Rhino REPL environment; if I (reset! rhino/loaded-libs #{}) in between REPL sessions, then the failure noted in the ticket does not occur, and the REPL appears to be quite healthy.

This shared state is currently preventing two scenarios that are highly desirable IMO:

1. the ability to restart ClojureScript REPLs that use the same type of environment
2. the ability to have multiple ClojureScript REPLs in flight at the same time

(FWIW, my broader use case is to be able to efficiently drive automated tests.)

It looks like I should be able to wedge these bits of shared (implementation detail) state into the respective REPL environment types (/ht Brenton for introducing those last year after Strange Loop), but I thought I'd mail here to see if anyone

(a) has already been whacking away at the problem(s), and/or
(b) knows this to be a thorny problem that won't readily yield to my typical brand of elbow grease.

Thanks,

- Chas

Chas Emerick

unread,
Jan 26, 2013, 7:20:22 AM1/26/13
to cloju...@googlegroups.com
Fixing this by bringing the loaded-libs set into the Rhino REPL environment type ended up being fairly straightforward, and is enough for me to call it a fix for CLJS-358.

However, resolving the same issues for browser REPL would be much more involved. The custom HTTP server for browser REPL precludes using e.g. sessions to track multiple browser REPL environments that would carry *all* of their respective state, eliminating any shared bits. I'll not be digging into resolving this at the moment, but it seems like the best path forward would be to eliminate cljs.repl.server (the custom HTTP server) and all the associated static resource-serving stuff in cljs.repl.browser, in favor of a standard Ring/Compojure app. That would make a fix for this shared state problem dead-simple (via sessions), and make it easy for users to host the browser REPL as part of their own Ring apps that they're running anyway. Hopefully there are a minimum of implementation details in that custom HTTP server relied upon by either the browser REPL environment or the browser-side bits in clojure.browser.repl.

I presume such changes wouldn't be suitable/welcome within the ClojureScript project itself (I'm happy to be contradicted by suitable authorities!), so I guess this would constitute a separate browser REPL implementation.

Cheers,

- Chas
> --
> You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to clojure-dev...@googlegroups.com.
> To post to this group, send email to cloju...@googlegroups.com.
> Visit this group at http://groups.google.com/group/clojure-dev?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Bodil Stokke

unread,
Jan 26, 2013, 7:39:21 AM1/26/13
to cloju...@googlegroups.com
I think you presume correctly - the assumption that everybody would be running Ring anyway is false. It's not even safe to assume that everybody interested in using ClojureScript client side would necessarily be running Clojure (or Cljs, for that matter) server side.

-- 
Bodil Stokke

Chas Emerick

unread,
Jan 26, 2013, 8:33:40 AM1/26/13
to cloju...@googlegroups.com
Sure…perhaps I let my personal preferences leak through a bit there.

However, at least today, everybody that is using browser-REPL *is* using Clojure.  (And perhaps a weaker general claim would be uncontroversial, that the majority of cljs usage is among those that use Clojure on the backend as well.)  If you wanted to use browser-REPL with e.g. node.js, then a corollary to what I described built on Ring would then be necessary for whatever its analogue is in the node.js stack.  Unless the browser-REPL's HTTP server is to be rewritten in ClojureScript (perhaps running atop node.js atop whatever js engine you have available, perhaps the forthcoming nashorn on the JVM?), this bifurcation seems necessary.

Cheers,

- Chas
Reply all
Reply to author
Forward
0 new messages