nbb

Gregory Bleiker 2025-05-19T15:28:49.614669Z

I'm having a hard time with async/await and promesa. Somehow, all combinations don't do what I think they do:

(defn start-server []
  (set! the-server (js/Deno.serve routefn)))

(defn stop-server [] (.shutdown the-server))

(defn restart []
  (await
   (p/-> (stop-server)
   (start-server))))
Is there anywhere else than the promesa doku (which seems to be a superset of what is ported to nbb) to read up on this? I've tried several combinations of p/do! with and without await above, none of which seem to wait for the shutdown to finish and then run the server again.

borkdude 2025-05-19T15:30:04.256859Z

are you actually invoking one of these functions?

Gregory Bleiker 2025-05-19T15:30:31.924679Z

yes, from the REPL

borkdude 2025-05-19T15:31:05.564179Z

yes, the promesa docs are the primary source of information on how to use promesa

borkdude 2025-05-19T15:31:20.310949Z

what are you trying to do in words, perhaps I'm able to give some guidance

Gregory Bleiker 2025-05-19T15:32:04.451369Z

.shutdown is an async fn, I'm trying to wait for it to finish and then launch start-server

Gregory Bleiker 2025-05-19T15:32:09.273409Z

this is for the restart command

Gregory Bleiker 2025-05-19T15:34:54.145459Z

I'd like the repl to block until the server is up again as well

borkdude 2025-05-19T15:35:49.211169Z

The way to do it should be this:

(require '[nbb.core :refer [await]]
         '[promesa.core :as p])

(def the-server nil)

(defn start-server []
  (set! the-server (js/Deno.serve (fn [m] (js/Response. "hello")))))

(defn stop-server []
  (when the-server (.shutdown the-server)))

(defn restart []
  (await
   (p/do! (stop-server)
          (start-server))))

(restart)

borkdude 2025-05-19T15:37:11.050199Z

I do notice it doesn't block in the nREPL

borkdude 2025-05-19T15:37:22.055229Z

so perhaps something broke there, but otherwise it should be what you want]

borkdude 2025-05-19T15:37:34.907309Z

or maybe it does block but it goes very quickly

borkdude 2025-05-19T15:37:47.870829Z

yeah I do think it works since I'm getting not a promise but a direct JS object back

borkdude 2025-05-19T15:37:55.217529Z

user=> (require '[nbb.core :refer [await]]
  #_=>          '[promesa.core :as p])
nil
user=> (def the-server nil)
#'user/the-server
user=>

user=> (defn start-server []
  #_=>   (set! the-server (js/Deno.serve (fn [m] (js/Response. "hello")))))
#'user/start-server
user=>

user=> (defn stop-server []
  #_=>   (when the-server (.shutdown the-server)))
#'user/stop-server
user=>

user=> (defn restart []
  #_=>   (await
  #_=>    (p/do! (stop-server)
  #_=>           (start-server))))
#'user/restart
user=> (restart)
#js {:addr #object[Object], :finished #<js/Promise[~]>, :shutdown #object[shutdown], :ref #object[ref], :unref #object[unref]}

Gregory Bleiker 2025-05-19T15:37:58.995879Z

thanks a lot for the advice, will try this. Which await is used if I don't refer from nbb.core?

borkdude 2025-05-19T15:38:14.820289Z

a wrong await for sure, I don't know which one :)

👍 1
borkdude 2025-05-19T15:39:12.409489Z

well, perhaps it works in the user namespace or so, not sure:

user=> (= await nbb.core/await)
true

borkdude 2025-05-19T15:39:22.824889Z

user=> (ns foo)
#object[pt foo]
foo=> (= await nbb.core/await)
Could not resolve symbol: await

borkdude 2025-05-19T15:42:03.875239Z

probably some special cases here for the REPL: https://github.com/babashka/nbb/blob/9119dbe9b5f660cb77d29058b3b762978ee4b939/src/nbb/impl/nrepl_server.cljs#L339

borkdude 2025-05-19T15:42:38.431339Z

no that's not it either

borkdude 2025-05-19T15:43:47.708909Z

no, there is no default await, you'll get an error if you don't refer it yourself

borkdude 2025-05-19T15:43:50.263859Z

$ lein repl :connect 61754
Connecting to nREPL at 127.0.0.1:61754
Could not resolve symbol: nrepl.core/version
user=> await
Could not resolve symbol: await

Gregory Bleiker 2025-05-19T16:02:39.377669Z

sorry, I had overlooked that I require it from nbb.core all the time

👍 1
Gregory Bleiker 2025-05-19T16:14:08.116139Z

in the code above, why doesn't the (.shutdown the-server) need an await? I would have assumed that this will always return a promise straight away?

borkdude 2025-05-19T16:37:04.442259Z

Await still returns a promise but only adds a signal for the REPL to block