2013-04-19 20 views
11

Właśnie rozpocząłem tworzenie usługi w Clojure. Jestem trochę zagubiony w podejściu do zamykania serwerów.Najlepsza droga do osadzenia NREPL na serwerze Clojure

Używam Clojure 1.5.1. Do rejestrowania używam wersji 1.5.3. Chcę osadzić NREPL na moim serwerze w celu wdrożenia hot-code.

To jest mój plik core.clj. Core jest moim głównym i używam powłoki aplikacji, która generuje "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)) 

Po uruchomieniu serwera nrepl uruchamia się zgodnie z oczekiwaniami, wysyłając komunikaty informacyjne do terminalu. Następnie łączę się z "nrepl" z Emacs. Nie ma problemu. Od Emacsa wykonuję "(extenium.core/stop)". W tym momencie otrzymuję komunikat "Stopping nrepl server" na Emacsie (co oznacza, że ​​stdout został przekierowany do klienta). Połączenie zostanie zamknięte (zgodnie z oczekiwaniami) i nigdy nie widzę komunikatu "Zatrzymany serwer nrepl". W porządku.

Patrzę na Terminal i nie widzę komunikatów "Zatrzymywanie ..." lub "Zatrzymano ...". Zamiast tego pojawia się następujący wyjątek:

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

Idealnie chcę następujące:

  1. aby móc zainicjować zamknięcie z klienta NREPL. Z wdzięcznością zamknij wszystkie połączenia klienta NREPL bez wyjątku. Wyłączenie z komunikatami rejestrowania skierowanymi do terminala (lub ewentualnie do pliku dziennika rotacyjnego).
  2. Przez czas trwania połączenia NREPL sklonuj dane wyjściowe rejestrowania zarówno do serwera (terminalu lub dziennika), jak i do wyjścia NREPL.
  3. Przechwytuj informacje o przychodzących połączeniach NREPL, wymieniaj je i rejestruj aktywność połączenia i rozłączenia.
  4. W końcu uwierzytelnij przychodzące połączenia NREPL.
  5. Nawet później, autoryzuj ich do działań, które wykonują.

Odpowiedz

2

Zastrzeżenie: Nie zrobiłem tego, ale wydaje się interesujące.

Za README, w szczególności w sekcji "Dlaczego nREPL?" powinieneś być w stanie zaimplementować 2 - 4, wprowadzając własny, niestandardowy transport, być może jedynie rozszerzając jeden z gotowych rozwiązań.

Samoczynne zatrzymanie serwera może wymagać rozszerzenia transportu w gnieździe. To, co opisujesz jako "pełne gracji zamknięcie", brzmi jak implementacja protokołu "Logout".

Autoryzacja czynności, które wykonują, wydaje się mniej prosta. Wygląda na to, że musisz zaimplementować niestandardowy Handler, być może ponownie zawijając default-handler z kodem autoryzacyjnym.

Powodzenia!