Передовой способ встраивания NREPL в сервер Clojure

Я только что начал разработку службы в 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))

Когда я «запускаю», nrepl-сервер запускается, как и ожидалось, с информационными сообщениями, поступающими в Терминал. Затем я подключаюсь к «nrepl» из Emacs. Без проблем. Из Emacs я выполняю "(extenium.core/stop)". В этот момент я получаю сообщение «Остановка сервера nrepl» в Emacs (что означает, что стандартный вывод был перенаправлен клиенту). Соединение закрывается (как и ожидалось), и я никогда не вижу сообщение «Stopped nrepl server». Отлично.

Я смотрю на Терминал и не вижу сообщений "Остановка..." или "Остановлено...". Вместо этого я получаю следующее исключение:

Exception in thread "nREPL-worker-0" java.lang.Error: java.net.SocketException: Socket closed

В идеале я хочу следующее:

  1. Чтобы иметь возможность инициировать завершение работы с клиента NREPL. Мягко закройте все клиентские соединения NREPL без исключения. Завершение работы с сообщениями журнала, направленными на терминал (или, в конечном итоге, с ротационным файлом журнала).
  2. На время соединения NREPL клонируйте выходные данные журнала как на сервер (терминал или журнал), так и на выходные данные NREPL.
  3. Собирайте информацию о входящих подключениях NREPL, присваивайте им имена и регистрируйте действия по подключению и отключению.
  4. В конце концов, аутентифицируйте входящие соединения NREPL.
  5. Еще позже разрешите им действия, которые они выполняют.

person jennykwan    schedule 19.04.2013    source источник


Ответы (1)


Отказ от ответственности: я этого не делал, но это кажется интересным.

Согласно README, в частности разделу "Почему nREPL?" вы должны быть в состоянии реализовать 2-4, реализуя свой собственный транспорт, возможно, просто расширяя один из готовых.

Грамотная остановка сервера может повлечь за собой расширение транспорта сокетов. То, что вы описываете как «мягкое завершение работы», звучит как реализация протокола «Выход из системы».

Авторизация действий, которые они выполняют, кажется менее простой. Похоже, вам нужно будет реализовать собственный обработчик, возможно, снова обернув default-handler кодом авторизации.

Удачи!

person noahlz    schedule 20.04.2013