2017-03-04 09:54:08 +07:00
{
" cells " : [
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
2018-08-13 07:49:30 +07:00
" This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/system-design-primer). "
2017-03-04 09:54:08 +07:00
]
} ,
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
" # Design an online chat "
]
} ,
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
" ## Constraints and assumptions \n " ,
" \n " ,
" * Assume we ' ll focus on the following workflows: \n " ,
" * Text conversations only \n " ,
" * Users \n " ,
" * Add a user \n " ,
" * Remove a user \n " ,
" * Update a user \n " ,
" * Add to a user ' s friends list \n " ,
" * Add friend request \n " ,
" * Approve friend request \n " ,
" * Reject friend request \n " ,
" * Remove from a user ' s friends list \n " ,
" * Create a group chat \n " ,
" * Invite friends to a group chat \n " ,
" * Post a message to a group chat \n " ,
" * Private 1-1 chat \n " ,
" * Invite a friend to a private chat \n " ,
" * Post a meesage to a private chat \n " ,
" * No need to worry about scaling initially "
]
} ,
{
" cell_type " : " markdown " ,
" metadata " : { } ,
" source " : [
" ## Solution "
]
} ,
{
" cell_type " : " code " ,
" execution_count " : 1 ,
" metadata " : {
" collapsed " : false
} ,
" outputs " : [
{
" name " : " stdout " ,
" output_type " : " stream " ,
" text " : [
" Overwriting online_chat.py \n "
]
}
] ,
" source " : [
" %% writefile online_chat.py \n " ,
" from abc import ABCMeta \n " ,
" \n " ,
" \n " ,
" class UserService(object): \n " ,
" \n " ,
" def __init__(self): \n " ,
" self.users_by_id = {} # key: user id, value: User \n " ,
" \n " ,
" def add_user(self, user_id, name, pass_hash): # ... \n " ,
" def remove_user(self, user_id): # ... \n " ,
" def add_friend_request(self, from_user_id, to_user_id): # ... \n " ,
" def approve_friend_request(self, from_user_id, to_user_id): # ... \n " ,
" def reject_friend_request(self, from_user_id, to_user_id): # ... \n " ,
" \n " ,
" \n " ,
" class User(object): \n " ,
" \n " ,
" def __init__(self, user_id, name, pass_hash): \n " ,
" self.user_id = user_id \n " ,
" self.name = name \n " ,
" self.pass_hash = pass_hash \n " ,
" self.friends_by_id = {} # key: friend id, value: User \n " ,
" self.friend_ids_to_private_chats = {} # key: friend id, value: private chats \n " ,
" self.group_chats_by_id = {} # key: chat id, value: GroupChat \n " ,
" self.received_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest \n " ,
" self.sent_friend_requests_by_friend_id = {} # key: friend id, value: AddRequest \n " ,
" \n " ,
" def message_user(self, friend_id, message): # ... \n " ,
" def message_group(self, group_id, message): # ... \n " ,
" def send_friend_request(self, friend_id): # ... \n " ,
" def receive_friend_request(self, friend_id): # ... \n " ,
" def approve_friend_request(self, friend_id): # ... \n " ,
" def reject_friend_request(self, friend_id): # ... \n " ,
" \n " ,
" \n " ,
" class Chat(metaclass=ABCMeta): \n " ,
" \n " ,
" def __init__(self, chat_id): \n " ,
" self.chat_id = chat_id \n " ,
" self.users = [] \n " ,
" self.messages = [] \n " ,
" \n " ,
" \n " ,
" class PrivateChat(Chat): \n " ,
" \n " ,
" def __init__(self, first_user, second_user): \n " ,
" super(PrivateChat, self).__init__() \n " ,
" self.users.append(first_user) \n " ,
" self.users.append(second_user) \n " ,
" \n " ,
" \n " ,
" class GroupChat(Chat): \n " ,
" \n " ,
" def add_user(self, user): # ... \n " ,
" def remove_user(self, user): # ... \n " ,
" \n " ,
" \n " ,
" class Message(object): \n " ,
" \n " ,
" def __init__(self, message_id, message, timestamp): \n " ,
" self.message_id = message_id \n " ,
" self.message = message \n " ,
" self.timestamp = timestamp \n " ,
" \n " ,
" \n " ,
" class AddRequest(object): \n " ,
" \n " ,
" def __init__(self, from_user_id, to_user_id, request_status, timestamp): \n " ,
" self.from_user_id = from_user_id \n " ,
" self.to_user_id = to_user_id \n " ,
" self.request_status = request_status \n " ,
" self.timestamp = timestamp \n " ,
" \n " ,
" \n " ,
" class RequestStatus(Enum): \n " ,
" \n " ,
" UNREAD = 0 \n " ,
" READ = 1 \n " ,
" ACCEPTED = 2 \n " ,
2017-03-08 12:37:11 +07:00
" REJECTED = 3 "
2017-03-04 09:54:08 +07:00
]
}
] ,
" metadata " : {
" kernelspec " : {
" display_name " : " Python 3 " ,
" language " : " python " ,
" name " : " python3 "
} ,
" language_info " : {
" codemirror_mode " : {
" name " : " ipython " ,
" version " : 3
} ,
" file_extension " : " .py " ,
" mimetype " : " text/x-python " ,
" name " : " python " ,
" nbconvert_exporter " : " python " ,
" pygments_lexer " : " ipython3 " ,
" version " : " 3.4.3 "
}
} ,
" nbformat " : 4 ,
" nbformat_minor " : 0
}