janet-lang/janet

Connections dropped in chat server example.

bakpakin opened this issue · 1 comments

Copying from discussion over at https://janet.zulipchat.com/#narrow/stream/409517-help/topic/TCP.20chat

(def conmap @{})

(defn broadcast [em msg]
  (eachk par conmap
         (if (not= par em)
           (if-let [tar (get conmap par)]
             (net/write tar (string/format "[%s]:%s" em msg))))))

(defn handler
  [connection]
  (net/write connection "Whats your name?\n")
  (def name (string/trim (string (ev/read connection 100))))
  (if (get conmap name)
    (do
      (net/write connection "Name already taken!")
      (:close connection))
    (do
      (put conmap name connection)
      (net/write connection (string/format "Welcome %s\n" name))
      (defer (do
               (:close connection)
               (put conmap name nil))
        (while true
          (if-let [msg (ev/read connection 100)]
            (broadcast name (string msg))
            (break)))))))

(defn main [& args]
  (printf "STARTING SERVER...")
  (flush)
  (def my-server (net/listen "127.0.0.1" "8000"))
  (forever
   (def connection (net/accept my-server))
   (ev/call handler connection)))

Hello, I'm trying to get a simple chat app running, but for some reason when 2 or more people are chatting, if one disconnects (using netcat) then another one will also be disconected, I think it has something to do with the break in the chat loop, but if I don't do that "nil hack", then the program will keep reading from a closed connection broadcasting empty strings all the time. I could use some help :P maybe I'm missing something. (I'm using janet 1.36.0-dev-c82fd106)

The issue seems to be that the the event loop is keeping a reference to an old fiber around. When we close one stream, it was killing a fiber that it wasn't supposed to, dropping other connections. We fix this by properly NULLing out the fiber reference once the read/write to socket ends in all cases, and adding a simulated chat on a chat server as a regression test.