Inspect state atom which gets updated by a ring handler

混江龙づ霸主 提交于 2019-12-24 16:00:41

问题


Consider the following scenario:

A minimal boot task starts up a http server:

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

(This might be launched in several ways, here it's ok to just run it from a nrepl session, e.g. started by boot repl from the terminal)

The handler is represented by the function handler inside the namespace myapp.server. The corresponding file looks like this:

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

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

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

This works, every time the address localhost:3000 is visited the the atom is updated and the new version is printed to stdout inside the repl.

How can the atom been inspected at any time?

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

yields an error. (...no such var...)

When trying the same thing from within an emacs cider nrepl connection, this previous attempt always shows up the initial value of the atom: {:n 0}


UPDATE

Here are the exact steps I do when using emacs/cider:

  1. cd projectdir
  2. start emacs
  3. cider-jack-in
  4. (boot (dev))
  5. Ctrl+C+C (in order to get a prompt again.)
  6. Then Testing with curl: getting responses + inside emacs updated atom is logged: {:n 1} .. {:n 2} ..
  7. Then, in the repl: (require 'myapp.server), takes a while: nil.
  8. finally: @myapp.server/state --> however: {:n 0}

回答1:


Your (...no such var...) error probably happens because you haven't require the myapp.server namespace. Attempts to see updates happening to your atom in CIDER REPL fail probably because your ring app runs in another JVM process than your REPL so the REPL sees only initial value as updates from ring handler happen in another JVM or it is enclosed in a separated classloader as it might be isolated by boot POD.

You have two options:

  • start your ring app with REPL server enabled and connect to it from another process (for example by using Server Socket REPL and connecting to it using telnet)

  • start your REPL and then start your ring app from it and you have access to all your loaded namespaces.

With the first approach you probably need to use boot-clj's nrepl option. When you configure it to start nREPL server then you can connect to it using boot repl -c (optionally providing the same coordinates as to boot-http nrepl options) or directly from CIDER using cider-connect.



来源:https://stackoverflow.com/questions/38924779/inspect-state-atom-which-gets-updated-by-a-ring-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!