Repository: facebookresearch/ParlAI

Issue:
Issue terminal chat service
Hello,

First of all thank you for this amazing framework.
I was trying to run the terminal chat example (code from today without changes except port).

It seems that there are only 'max_worker' clients possible to connect in total. For example when I set max_worker=1 in the config.yml, I can connect with the client one time successfully. But when I stop the client ('[DONE]'), start it again and it gets stuck right at the beginning.

How can I prevent the server from getting stuck once >max_workers clients have been connected? I already tried removing the agent from memory, however it seems that the issue is that the thread is just not ending.

![image](https://user-images.githubusercontent.com/32954413/107663358-94f0e000-6c8b-11eb-8cd3-97fd1806197a.png)

I use Python 3.7.5 and Ubuntu 18.04 LTS.



Discussion:
@klshuster any idea?

Resolving patch:
diff --git a/parlai/chat_service/services/terminal_chat/client.py b/parlai/chat_service/services/terminal_chat/client.py
--- a/parlai/chat_service/services/terminal_chat/client.py
+++ b/parlai/chat_service/services/terminal_chat/client.py
@@ -11,6 +11,13 @@
 import threading
 from parlai.core.params import ParlaiParser
 
+# the socket callback functions operate asynchronously.
+# upon exit of a chat, we do not want the user to view any additional messages from the server.
+# alas, it is necessary to send two messages ([DONE], and EXIT) in order to fully exist the world pool
+# to prevent receiving a message after sending [DONE], we track the user's state with
+# this global variable.
+RUNNING = True
+
 
 def _get_rand_id():
     """
@@ -35,6 +42,8 @@ def on_message(ws, message):
     :param ws: a WebSocketApp
     :param message: json with 'text' field to be printed
     """
+    if not RUNNING:
+        return
     incoming_message = json.loads(message)
     print("\033[0m\n")
     print("Bot: " + incoming_message['text'])
@@ -71,16 +80,22 @@ def _run(ws, id):
 
     :param ws: websocket.WebSocketApp
     """
+    global RUNNING
     while True:
         x = input("\033[44m Me: ")
         print("\033[0m", end="")
         data = {}
         data['id'] = id
         data['text'] = x
+        if x == "[DONE]":
+            RUNNING = False
         json_data = json.dumps(data)
         ws.send(json_data)
         time.sleep(1)
         if x == "[DONE]":
+            time.sleep(1)
+            data['text'] = 'EXIT'
+            ws.send(json.dumps(data))
             break
     ws.close()
 
diff --git a/parlai/chat_service/tasks/chatbot/worlds.py b/parlai/chat_service/tasks/chatbot/worlds.py
--- a/parlai/chat_service/tasks/chatbot/worlds.py
+++ b/parlai/chat_service/tasks/chatbot/worlds.py
@@ -121,12 +121,15 @@ def parley(self):
                 {
                     'id': 'Overworld',
                     'text': 'Welcome to the overworld for the ParlAI messenger '
-                    'chatbot demo. Please type "begin" to start.',
-                    'quick_replies': ['begin'],
+                    'chatbot demo. Please type "begin" to start, or "exit" to exit',
+                    'quick_replies': ['begin', 'exit'],
                 }
             )
             self.first_time = False
         a = self.agent.act()
+        if a is not None and a['text'].lower() == 'exit':
+            self.episode_done = True
+            return 'EXIT'
         if a is not None and a['text'].lower() == 'begin':
             self.episodeDone = True
             return 'default'


Test patch: