You just bought a new home and you go in the basement. You are shocked to see that it is filled up to the ceiling with a lot of things. Guess what, the previous home owner was a hoarder. He left without cleaning and now you have to deal with his unwanted toasters, buckets, mattresses and his old nasty smelling shoes.
But you have an advantage. You are a Software Developer. You can make an Auction website and auction all of this stuff to earn money. May be not those smelly shoes. They need to go to garbage or personally get thrown through the window of the previous home owner's current home 😮💨.
Now, you get to the drawing board and you figured that an Auction would require the following things.
- A Frontend Client, to display the data (Bids)
- A Backend Server, to store the data
- A flow of data from Server to Client when the data changes (Auction Bids change)
First Attempt
Coming from a background where you have a day job of creating NodeJS, React apps, for this application you also create a NodeJS REST API and a React Frontend application. This setting is a Client/Server architecture in which Client (ReactJS app) will always request for data to the Server (NodeJS API) but never the otherwise.
The first two items in the above list are marked done. Now you start to work on the 3rd item: How the data flow will happen?
Since it is a Client/Server architecture to update the data on clients, clients have to request the data every time they want to update the data (Show next bids).
The solution you adopt is, having an infinite loop on the client, constantly checking server for the data change every 1 second. If there is a change the clients will pull the new data. (Client oriented broadcast).
On launch date 10,000 bidders show up on your website. You are happy to see the $$$ amount going up and imagining yourself driving your brand new Lamborghini when the reality hits. The server went down. Wait...What happened??
Your website went down because the server was overloaded with the amount of requests it has to serve for 10,000 clients. Every client is requesting new data every second, which means your server is getting 10,000 HTTP requests in one second, 60,000 in one minute. Poor server.
You pray to God that somehow he gives you a solution and God sends this Article to you. (Or let you find it of the internet).
Second Attempt
In this attempt, we do things a little differently. We figure out what are the bottlenecks.
- Too many requests to the server
- Too frequent requests to the server
In-Person vs Online Auction
If we take an example of a real life, in-person auction, we can find some similarities. Host of the auction act as a server where the people sitting there bidding, act as clients. But notice an important thing about the broadcast. In in-person auction, the information is flowing from the host of the auction to the bidders via voice. It makes more sense for the host to shout out the bids, rather than each bidder whispering the host to ask what is the current bid on this product. Host shouting saves a lot of time and a lot of effort while the bidders keeps synced with the auction.
We will use the same pattern here. If we shift the responsibility of broadcast to the Server, Clients do not have to request the information every second. Server should know when the data is changed and on this data change, it should send the new data to all the clients. Clients should just receive this data and display it.
Is HTTP good for the Broadcast?
Using HTTP (as we do in REST API), it is not possible because HTTP communication starts from client by placing an HTTP request on the server.
We have to use a different protocol for this problem, which allows communication to be originated from the server. 'Web Sockets' come to our rescue
Since I am a developer, it is my utmost duty to use ChatGPT for it's definition. According to ChatGPT:
WebSockets are a protocol for bi-directional, real-time communication between web browsers and servers over a single, long-lived connection.
We setup a Web Socket server. Like ExpressJS on NodeJS we have a very amazing package for it called Socket.IO.
Implementing Web Sockets in our App
Every time a client is connected to the Socket server it assigns the connection an ID using which we can interact with the connection for sending and receiving the data.
Each time the server detects a change in the data, server should engage all the client connections and send the new data to these client (Broadcasting).
One design pattern we can use for this application could be Publish/Subscribe pattern. In this pattern the clients gets subscribed to a stream of data and whenever there is a new data, server pushes the data to the subscribed clients.
A simple implementation of this approach would be to create an array to keep track of active connections. Whenever a new client appears we add the connection to the client to this array. If the client closes the connection, we remove that connection from the array.
Whenever there is a new data available, we can iterate through this array and one-by-one push the data on the iterated connection. A pseudo code implementation would be something like this:
connections[] = []
Function onNewConnection(connection){
connections.push(connection)
}
Function onConnectionRemoved(connection){
connections.delete(connection)
}
Function onDataChange(newData){
for(connection in connections){
connection.send(newData)
}
}
The next day you implement this fix and you run the auction and following things happen
- Now the number of requests are significantly reduced because the new data is not requested every second. It will be requested only when the data changes (New bids appear).
- The auction is also perfectly synced because there is no delay between the point where auction updates and the point where auction data is broadcasted.
The auction ends and at the end of the day, you have One Million Dollars in the bank. You can now have a Lamborghini and you should thank me for that.
So overall, it is a good idea for a broadcasting service to make the data keeper be the responsible for data broadcasting, rather than the consumer of the broadcast should have to request the data. One way to do it is Socket based communication.
Connect
Blog👉 https://hariscodes.com/
Twitter👉 https://twitter.com/tweetharisahmad
Instagram👉 https://www.instagram.com/hariscodes/
Top comments (0)