Лучший способ внедрения NREPL в Clojure Server
Я только начал разработку сервиса в Clojure. Я немного потерян в том, как подойти к остановке сервера.
Я использую Clojure 1.5.1. Для регистрации я использую Timbre 1.5.3. Я хочу встроить NREPL в мой сервер для оперативного развертывания кода.
Это мой файл core.clj. Я использую ядро, и я использую оболочку приложения, которую генерирует "lein new app".
(ns extenium.core
(:require [taoensso.timbre :as t]
[clojure.tools.nrepl.server :as nrs])
(:gen-class))
(def nrepl-server)
(defn start-nrepl-server []
(t/info "Starting nrepl server on port 8628")
(alter-var-root #'nrepl-server
(constantly
(nrs/start-server :port 8628)))
(t/info "Started nrepl server"))
(defn stop-nrepl-server []
(t/info "Stopping nrepl server")
(nrs/stop-server nrepl-server)
(t/info "Stopped nrepl server"))
(defn start []
(alter-var-root #'*read-eval*
(constantly
false))
(start-nrepl-server))
(defn stop []
(stop-nrepl-server))
(defn -main [& args]
(start))
Когда я запускаю lein, nrepl-сервер запускается, как и ожидалось, с информационными сообщениями, идущими в Терминал. Затем я соединяюсь с "nrepl" из Emacs. Нет проблем. Из Emacs я выполняю "(extenium.core / stop)". В этот момент я получаю сообщение "Остановка сервера nrepl" в Emacs (это означает, что stdout был перенаправлен клиенту). Соединение закрывается (как и ожидалось), и я никогда не вижу сообщение "Остановлен сервер nrepl". Хорошо.
Я смотрю на Терминал и не вижу сообщений "Остановка..." или "Остановка...". Вместо этого я получаю следующее исключение:
Exception in thread "nREPL-worker-0" java.lang.Error: java.net.SocketException: Socket closed
В идеале я хочу следующее:
- Чтобы иметь возможность инициировать отключение от клиента NREPL. Изящно закройте все клиентские соединения NREPL без исключения. Завершение работы с сообщениями регистрации, направленными к Терминалу (или в конечном счете, вращающийся файл журнала).
- Во время подключения NREPL клонируйте выходные данные журналов как на сервер (терминал или журнал), так и на выходные данные NREPL.
- Захватывайте информацию о входящих соединениях NREPL, присваивайте им имена, а также регистрируйте действия по подключению и отключению.
- В конце концов, аутентификация входящих соединений NREPL.
- Даже позже, авторизуйте их для действий, которые они выполняют.
1 ответ
Отказ от ответственности: я не сделал этого, но это кажется интересным.
Согласно README, в частности, раздел "Почему nREPL?" у вас должно получиться реализовать 2 - 4, реализовав свой собственный транспорт, возможно, просто расширив один из готовых.
Изящная остановка сервера может повлечь за собой расширение транспорта сокетов. То, что вы описываете как "постепенное отключение", звучит как реализация протокола "Logout".
Авторизованные действия, которые они выполняют, кажутся менее простыми. Похоже, вам нужно будет реализовать пользовательский обработчик, возможно, снова оборачивая default-handler
с кодом авторизации.
Удачи!