Fred T-H avatar Fred T-H committed bb6df31

Fixing info after otp-izing Chut

Comments (0)

Files changed (1)

 * Javascript JSONP client
 * Basic history logs from previous conversations
 * General test suite
+* Should be a standard OTP application
 
 === How it works ===
 The first concept to understand is the idea of clients and users. A client is basically a connection from a socket, web server, browser tab, whatever. The user is a bunch of processes that represent a real world user. Clients connect to a user and can route messages through them for another user, which in turns routes them to that user's clients.
 Users are composed of a supervisor, a gen_fsm and a gen_event:
 
 ==== Supervisor ====
-The supervisor adopts a one-for-all restart strategy for the FSM and event manager, making sure the user can't exist without them. The supervisor also acts as an entry point to the user hierarchy. The whole group can then be killed that way.
+The supervisor structure goes as follow:
+{{{
+#!text
+.                       chut_sup
+                   /              \
+         chut_user_supersup   chut_webserver_sup
+              / | \                        |
+       chut_user_sup (many)         chut_webserver (worker)
+      /                  \
+   monitor (worker)    manager (worker)
+}}}
+(I'll replace this as soon as I'm on a computer with Visio)
+
+Here, //chut_sup// is the whole application's supervisor.
+                  
+The //chut_user_supersup//  acts as an entry point to the user hierarchy. A user can be killed by terminating then deleting the children from it. The //chut_user_sup// supervisor adopts a one-for-all restart strategy for the FSM and event manager, making sure the user can't exist without them. After that, there's only //chut_webserver_sup//, responsible for monitoring mochiweb's server.
 
 ==== gen_event ====
 The event manager is responsible for routing messages from user to user, and also from a user to each of its clients. Each message sent from or to a given user must pass through the event manager. 
 
 Different event handlers attached to the event manager will be dealing with routing messages:
 
-* //usr_dispatch_handler//: Takes messages you send and routes them to another user. There is only one of these per user.
-* //usr_listen_handler//: Takes any kind of message received and transmits it to the client. The format of the message is altered to be {UserId, {received, From, Message}} or {UserId, {sent, To, Message}} so a given process can hold more than one client connection. There is one handler of this kind per client and each of them is added with gen_event:add_sup_handler/3, which guarantees that if the client dies, the handler also dies (the opposite is also true, except for a normal exit).
+* //chut_user_dispatch_handler//: Takes messages you send and routes them to another user. There is only one of these per user.
+* //chut_user_listen_handler//: Takes any kind of message received and transmits it to the client. The format of the message is altered to be {UserId, {received, From, Message}} or {UserId, {sent, To, Message}} so a given process can hold more than one client connection. There is one handler of this kind per client and each of them is added with gen_event:add_sup_handler/3, which guarantees that if the client dies, the handler also dies (the opposite is also true, except for a normal exit).
 
-Another handler, namely //usr_history_handler//, exists with the sole purpose of accumulating the messages sent through a user. When the notification {From, history} (where //From// is a PID) is sent, this handler will send back a list of recent messages routed through the user.
+Another handler, namely //chut_user_history_handler//, exists with the sole purpose of accumulating the messages sent through a user. When the notification {From, history} (where //From// is a PID) is sent, this handler will send back a list of recent messages routed through the user.
 
 These three handlers are enough to do all the message routing and history keeping. Additional handlers could be added to do logging, presence updates, etc.
 
 
 ==== gen_fsm ====
-The finite state machine acts as a manager for state. It tracks the addition and deletion of //usr_listen_handler//s to the user. When there are no listeners left on the user, the state machine falls into a waiting state. If no handler is added within the given time limit (determined by the supervisor), the FSM kills the supervisor, bringing down the user itself.
+The finite state machine acts as a manager for state. It tracks the addition and deletion of //chut_user_listen_handler//s to the user. When there are no listeners left on the user, the state machine falls into a waiting state. If no handler is added within the given time limit (determined by the supervisor), the FSM kills the supervisor, bringing down the user itself.
 
 This time delay allows a user with only 1 client in a browser to refresh pages and stay connected.
 
 * Adding logging to messages sent and received
 * Notifying the user when someone he's talking to disconnects
 * Specifying functions to deal with netsplits and user registration
-* Turn Chut into an OTP application
 * Add more unit tests
 * Benchmark the performances
 * Making the conversation history more flexible
 
 To notify a user someone he's talking to has disconnected, two options are possible. The first one is to add a lookup on each message sent (from the dispatch handler), which would then report that event to all connected clients. The second option is that when a discussion starts between two users, the FSM starts monitoring the other user. Whenever the FSM receives a message mentioning the death of a monitored user, the clients are made aware of it. This last option would require the potential addition of new functions to usr.erl, but would reduce the amount of lookups made within the global module and would let the status of the other user be known in real time rather than the sending of a message.
 
-Turning Chut into an OTP application might be a little complex in terms of refactoring. The current plan is to add a top-level supervisor per node where all users will be registered. The addition and removal of users to a system will thus need to be routed through that supervisor with supervisor:start_child/2 and supervisor:terminate_child/2 (followed by supervisor:delete_child/2). This represents a little gain in complexity opposed to a good gain in simplicity when it comes to deploying and managing Chut. The web server implementation will be separate from this application. The web server will likely need to be turned to its own OTP application with a dependency on Chut, if they're to run on the same nodes.
-
 More unit tests should be one of the top priority also. So far, only a general common test suite exists, testing the general behavior of the chat users and client modules. A finer grained testing approach could help optimize some potential bottlenecks and increase confidence in the code. Load and performance testing is also needed, in order to know what load the prototype can support and if using global the way it is used might become a bottleneck when under heavy load.
 
 As for the conversation history, it should be trivial to make it better (only keeping //x// messages in memory) to something more flexible. The history message could be changed to take the form {From, {history, LastId}} where LastId might just be {now(), make_ref()} and would refer to the last message read. Otherwise,  having a conversation history that could be dispatched depending on the receiving party would also be useful. However, given what's left to do in other areas, these ameliorations will be delayed a bit.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.