- WebSocket: Communication between the client and server
- Parallel processing using Akka toolkit
- Backend using Redis
Framework used for server: Play Framework
Why use Play Framework?
- It's great for building a quick MVC
- Play handles every request in an asynchronous, non-blocking way.
- The controller code below, the returned Result is internally enclosed in a promise
public Result index() {
return ok("Got request " + request() + "!");
}
- Integration with Akka is easy
The application is configured to start a Netty Server. Currently the API return text/html content type, this can be changed easily to accomodate JSON (I tried to focus on building a non-blocking scalable application)
- Low-latency two-way communication becomes possible on a single connection if you implement WebSocket.
- Sending an HTTP request is no longer required every time a user sends a message, allowing more resources to be used efficiently.
- The payload format for websocket connection is JSON.
- I have not implemented a mechanism to disconnect and reconnect in case of network unstability (Although there is a chatbot that tries to keep the session alive).
- Each actor is assigned its own light-weight thread and runs within that thread.
- By using streams we get the added benefit of backpressure, a form of flow control which limits the incoming messages until there is demand downstream
- Just used a redis cache to store information.
- Did not give much attention to model creation and ORM.
- Store users as Hashes O(1) complexity.
- Conversation history is stored as a list (to maintain order - O(n) complexity).
The app handles the below scenarios:
- Create User - Create two users atleast so that you can chat with the other person
Takes a username and password and creates a new user in a persisted data store. For example, the endpoint might accept PUT or POST at /users.
- Send Message
Takes a sender, recipient, and message and saves that to the data store. For example, the endpoint might accept PUT or POST at /messages. Three different message types are supported. (1) is a basic text-only message. (2) is an image link. (3) is a video link. The image and video links are saved with some additional metadata: width and height for the image, length of the video and source (YouTube, Vevo) for the video. For the purpose of the challenge, you can hard-code the metadata to some fixed values when you're saving the message.
- Fetch Messages
Takes two users and loads all messages sent between them. This call should also take two optional parameters in order to support pagination: the number of message to show per page and which page to load. For example, the endpoint might accept GET at /messages.
- Run docker-compose build (it builds the containers)
- docker-compose up
Resource: https://engineering.linecorp.com/en/blog/detail/85