This is a Swiggy frontend interview question.
Implement an analytics SDK that exposes log events, it takes in events and queues them, and then starts sending the events. The SDK should adhere the following properties.
Input:
const sdk = new SDK();
sdk.logEvent("event 1");
sdk.logEvent("event 2");
sdk.logEvent("event 3");
sdk.logEvent("event 4");
sdk.logEvent("event 5");
sdk.logEvent("event 6");
sdk.logEvent("event 7");
sdk.logEvent("event 8");
sdk.logEvent("event 9");
sdk.logEvent("event 10");
sdk.send();
Output:
"Analytics sent event 1"
"Analytics sent event 2"
"Analytics sent event 3"
"Analytics sent event 4"
"-----------------------"
"Failed to send event 5"
"Retrying sending event 5"
"-----------------------"
"Analytics sent event 5"
"Analytics sent event 6"
"Analytics sent event 7"
"Analytics sent event 8"
"-----------------------"
"Failed to send event 9"
"Retrying sending event 9"
"-----------------------"
"Analytics sent event 9"
"Analytics sent event 10"
Breaking the problem statement into subproblems we can create this SDK in three steps.
The most important part of this function is that the events will be sent after a delay of 1 second and fails n % 5 times.
We can do the same by extending the sleep function.
Create a new Promise and inside that run a setTimeout that will resolve the promise.
To the same, we will add one extra condition that will check if the current execution is n % 5 then reject, else resolve.
// function to delay the exection
wait = () => new Promise((resolve, reject) => {
setTimeout(() => {
// reject every n % 5 time
if(this.count % 5 === 0){
reject();
} else {
resolve();
}
}, 1000);
});
We have to store the events so that they can be sent one by one also we need a tracker so that we can reject for each n % 5.
We can create a class and initialize these in the constructor.
class SDK {
constructor(){
// hold the events
this.queue = [];
// track the count
this.count = 1;
}
// push event in the queue
logEvent(ev) {
this.queue.push(ev);
}
}
The final part is sending the events, for this, we can create a helper function, that will recursively call itself and keep on sending one-one events every time.
This will be an async function and in each call, get the first element from the queue and try the wait(), if it resolves then print the log or perform any other operation, else if it fails, push the event back in the queue for retry. Finally, recursively call the same function for the next operation.