2016-08-12 7 views
1

Рассмотрим следующий сценарий:Проверьте состояние атома, который обновляется с помощью кольцевого обработчика

Минимальная задача загрузки запускает HTTP сервер:

(boot (serve :handler 'myapp.server/handler 
      :port 3000)) 

(Это может быть запущен несколькими способами , здесь можно просто запустить его из сеанса nrepl, например, запущен boot repl с терминала)

Обработчик представлен функцией handler внутри пространства имен myapp.server. Соответствующий файл выглядит следующим образом:

(ns myapp.server (:require ...)) 

(defonce server-state (atom {:nr 0})) 

(defn handler [req] 
    (prn (swap! server-state update :nr inc)) 
    {:body "Answer.\n"}) 

Это работает, каждый раз, когда адрес локальный: 3000 посетил атом обновляется и новая версия печатается на стандартный вывод внутри REPL.

Как можно проверить атом в любое время?

boot.user=> @myapp.server/server-state 

дает ошибку. (...no such var...)

При попытке же самое изнутри соединение nrepl Emacs сидра, это предыдущая попытка всегда показывается начальное значение атома: {:n 0}


UPDATE

Вот точные шаги, которые я выполняю при использовании emacs/сидра:

  1. cd ProjectDir
  2. начало emacs
  3. cider-jack-in
  4. (boot (dev))
  5. Ctrl+C+C
  6. Тогда тестирование с curl (для того, чтобы получить приглашение снова.): получать ответы + внутри Emacs обновляется атом регистрируется: {:n 1} .. {:n 2} ..
  7. Затем в реплике: (require 'myapp.server), занимает время: nil.
  8. наконец: @myapp.server/state -> однако: {:n 0}
+0

Вы уверены, что ваш обработчик звонка и ваш реплика работают в одном и том же процессе JVM? –

ответ

0

Ваша ошибка (...no such var...) вероятно происходит потому, что вы не требуют myapp.server имен. Попытки увидеть обновления, происходящие с вашим атомом в CIDER REPL, возможно, из-за того, что ваше кольцевое приложение работает в другом JVM-процессе, чем REPL, поэтому REPL видит только начальное значение, поскольку обновления из обработчика звонков происходят в другой JVM или заключены в разделенный загрузчик классов как он может быть изолирован boot POD.

У вас есть два варианта:

  • начать свое безымянное приложение с REPL сервером включен и подключиться к нему из другого процесса (for example by using Server Socket REPL and connecting to it using telnet)

  • запустить REPL, а затем начать свое кольцо приложения от него, и вы имеют доступ ко всем загруженным пространствам имен.

При первом подходе вам, вероятно, необходимо использовать опцию boot12c. Когда вы настроите его для запуска сервера nREPL, вы можете подключиться к нему с помощью boot repl -c (необязательно с теми же координатами, что и для параметров загрузки-http nrepl) или directly from CIDER с использованием cider-connect.

+0

Я добавил некоторое подробное обновление в конце сообщения ... –

+0

Единственное, что я могу себе представить, это то, что (boot ..) порождает новый процесс JVM. –

+0

Да, это может вызвать новый процесс JVM. Вы можете проверить список процессов JVM до и после выполнения '(boot (dev))'. Это также может быть проблемой класса, поскольку он использует POD для изоляции зависимостей задач (https://github.com/boot-clj/boot/wiki/Pods). –