title: Implementing multiple session support in a chatbot
body: <p>I am currently implementing a Chatbot purely in python.</p>
  
  <p>In my current implementation, each time the user starts a new chat from a session, another Chatbot instance is launched and hence the Chatbot starts from the initial state.</p>
  
  <p>I wish to change that behaviour and make it similar to let's say chat on Facebook/Messenger, in which you can seamlessly move between sessions while having a chat without inconsistencies. Namely, I want these attributes:</p>
  
  <ol>
  <li>If the user enters anything from let's say session A it should be immediately visible in all ongoing sessions. Similarly, the Chatbot reply should be visible in all the devices immediately.</li>
  <li>Have all sessions show the same chat history</li>
  </ol>
  
  <p>To implement the first point, I used <a href="https://channels.readthedocs.io/en/latest/tutorial/part_2.html" rel="nofollow noreferrer">this example</a> from the django-channels docs and modified it by creating a single group/chatroom for each user. All the sessions from the same user get connected to the same group/chatroom and hence receive all the messages in the group/chatroom regardless of where they were sent from.</p>
  
  <p>However, this implementation currently has a bug. Each time that a user is connected, it initializes a Chatbot instance which starts from the initial state again while the older connections have Chatbot instances that are currently at a different state. </p>
  
  <p>This leads to inconsistent replies which are different based on which window the user typed something in.</p>
  
  <p>Basically instead of having two sessions talk to the same Chatbot instance, we have two sessions talking to two different Chatbot instances and messages from all these four sources are getting added to the same chatroom. </p>
  
  <p>Moreover, we are wasting resources by keeping multiple Chatbot instances per user which increases with the number of currently active sessions.</p>
  
  <p>I want all of the user windows to interact with the same Chatbot instance. What would be the best way to implement that?</p>
  
  <p>Currently I can think of three solutions:</p>
  
  <ol>
  <li>Creating another Django project the Chatbot and make requests to that HTTP server. The Chatbot state is maintained in that server and any request from the user will go to the same Chatbot instance. 
  
  <ul>
  <li>This is straightforward to implement for me (simply spin up another server)</li>
  <li>This naturally solves all the problems regarding state as all the instances will query the same Chatbot object</li>
  </ul></li>
  <li>Creating a <em>Master</em> channel thread which will hold the actual Chatbot instance(a python object) and any new channels will will defer to it for the reply from the Chatbot. 
  
  <ul>
  <li>This will be complicated to implement </li>
  <li>I will have to maintain which thread is master and which ones are slaves </li>
  <li>In situations where a user closes the master thread connection I will somehow have to change one of the slave connections to a master connection and pass the entire object(?!) or atleast pass the state variable and re-create the chatbot instance.</li>
  </ul></li>
  <li>Spawn an independent thread/process in python for the chatbot instance and have all the channel connections talk to that thread/process .
  
  <ul>
  <li>This will be hard for me to implement as I don't currently know how to do IPC in python</li>
  </ul></li>
  </ol>
  
  <p>Are there any other solutions possible? What would be the ideal solution?</p>
  
  <p>I am using the following technologies:</p>
  
  <ol>
  <li><a href="https://www.djangoproject.com/" rel="nofollow noreferrer">Django</a> as the main backend, with <a href="https://channels.readthedocs.io/en/latest/" rel="nofollow noreferrer">Django Channels</a> for WebSockets</li>
  <li><a href="https://rasa.com/docs/nlu/" rel="nofollow noreferrer">RASA NLU</a> for the NLU component of the chatbot and a finite state machine model implemented using <a href="https://github.com/pytransitions/transitions" rel="nofollow noreferrer">pytransitions</a> for the dialog management in python</li>
  </ol>