forked from clj-python/libpython-clj
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathembedded.clj
68 lines (56 loc) · 2.47 KB
/
embedded.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
(ns libpython-clj2.embedded
"Tools for embedding clojure into a python host process.
See jbridge.py for python details. This namespace relies on
the classpath having nrepl and cider-nrepl on it. For example:
```console
clojure -SPath '{:deps {nrepl/nrepl {:mvn/version \"0.8.3\"} cider/cider-nrepl {:mvn/version \"0.25.5\"}}}' ...
```"
(:require [libpython-clj2.python.ffi :as py-ffi]
[nrepl.server :as server]
[nrepl.cmdline :as cmdline]
[clojure.tools.logging :as log]))
(defn initialize!
"Initialize python when this library is being called *from* a python program. In
that case, unless libpath is explicitly provided the system will look for the
python symbols in the current executable."
([] (py-ffi/set-library! nil))
([libpath] (py-ffi/set-library! libpath)))
(defonce ^:private repl-server* (atom nil))
(defn stop-repl!
"If an existing repl has been started, stop it. This returns control to the
thread that called `start-repl!`."
[]
(swap! repl-server*
(fn [server]
(when server
(try
(locking #'repl-server*
(server/stop-server server)
(.notifyAll ^Object #'repl-server*))
nil
(catch Throwable e
(log/errorf e "Failed to stop nrepl server!")
nil))))))
(defn start-repl!
"This is called to start a clojure repl and block the thread. This function does not return
control to the calling thread until another thread calls `stop-repl!; this design is
explicit to ensure the python GIL is released and thus when connected to the REPL you can
use Python.
If an existing repl server has been started this returns the port of the previous
server else it returns the port of the new server.
To return control to the calling thread call `stop-repl!`.
Options are the same as the command line options found in nrepl.cmdline."
([options]
(when-not @repl-server*
(let [options (cmdline/server-opts
(merge {:middleware '[cider.nrepl/cider-middleware]}
options))
server (cmdline/start-server options)
_ (reset! repl-server* server)]
(cmdline/ack-server server options)
(cmdline/save-port-file server options)
(log/info (cmdline/server-started-message server options))
(locking #'repl-server*
(.wait ^Object #'repl-server*))))
(:port @repl-server*))
([] (start-repl! nil)))