Skip to content

Instantly share code, notes, and snippets.

@RajatNair
Last active May 4, 2020 18:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RajatNair/cc1f18d29904ef05ad8e408a2797b75a to your computer and use it in GitHub Desktop.
Save RajatNair/cc1f18d29904ef05ad8e408a2797b75a to your computer and use it in GitHub Desktop.
Request Queuing using Vanilla JavaScript and Typescript - https://stackblitz.com/edit/typescript-cdyebd
<h3>Request Queueing using Vanilla Javascript and Typescript</h3>
<div id="app"></div>
<div>
<h4>Console</h4>
<ol id="console">
</ol>
</div>
// Import stylesheets
import "./style.css";
// Write TypeScript code!
const consoleLog: HTMLElement = document.getElementById("console");
class Server {
private _serverEndpoints;
constructor() {
this._serverEndpoints = this.createEndpointQueue();
}
// Add Endpoint
add = (endpoint, priority, usecase) => {
consoleLog.innerHTML += `<ul>Adding server endpoint <i>${endpoint}</i> based on priority <i>${priority}</i> for <i>${usecase}</i> usecase</ul>`;
this._serverEndpoints.enqueue(endpoint);
};
// Call Endpoint
call = usecase => {
let apiResponse;
if (this._serverEndpoints.length > 0) {
if (usecase === "error") {
apiResponse = simulateApiCall(
this._serverEndpoints.dequeue(),
"API is down!",
1500
);
} else {
const url = this._serverEndpoints.dequeue();
apiResponse = simulateApiCall(
url,
`No response from API <i>${url}</i> in expected time.`,
3500
);
}
apiResponse
.then(data => {
console.log(data);
})
.catch(data => {
consoleLog.innerHTML += `<ul><b>Server response</b> - ${
data.message
} </ul>`;
consoleLog.innerHTML += `<ul>Attempting next API</ul>`;
this.call(usecase);
});
} else {
consoleLog.innerHTML += `<ul>All endpoints tried for ${usecase} usecase</ul><ul>&nbsp;</ul>`;
}
};
// Using simple queue instead of priority queue
createEndpointQueue = () => {
const endpointQueue = [];
return {
enqueue(url) {
endpointQueue.unshift(url);
},
dequeue() {
return endpointQueue.pop();
},
get length() {
return endpointQueue.length;
}
};
};
}
const simulateApiCall = (url, msg, delay = 1000): Promise<unknown> => {
consoleLog.innerHTML += `<ul>Calling API at endpoint - <i>${url}</i> </ul>`;
return new Promise((resolve, reject) => {
setTimeout(() => {
reject({ status: 500, message: msg });
}, delay);
});
};
// queue all requests to server
// after timeout or error
// switch to different server
// make 1 call - switch to different on error or timeout
const serverError = new Server();
// Assuming servers are added based on priority
serverError.add("https://server-one/api", 1, "Error");
serverError.add("https://server-two/api", 2, "Error");
serverError.add("https://server-three/api", 3, "Error");
serverError.call("error");
setTimeout(() => {
const serverTimeout = new Server();
serverTimeout.add("https://server-one/api", 1, "Timeout");
serverTimeout.add("https://server-two/api", 2, "Timeout");
serverTimeout.add("https://server-three/api", 3, "Timeout");
serverTimeout.call("timeout");
}, 5000);
@RajatNair
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment