Implementation of a technical code challenge.
I enjoyed this challenge a lot and got to learn & use 4 technologies I didn't get to use before - d3js
, WebSockets
, NotificationAPI
& CSS grid
display.
Build a a browser-based CPU load monitoring application. This application will display time-series data. A user should be able to view your application to answer the following questions about their computer:
- What is my computer's current average CPU load?
- How did the average CPU load change over a 10 minute window?
- Has my computer been under heavy CPU load for 2 minutes or more? When? How many times?
- Has my computer recovered from heavy CPU load? When? How many times?
- The front-end application should communicate with a local back-end service to retrieve CPU load average information from your computer (see below).
- The front-end application should retrieve CPU load information every 10 seconds.
- The front-end application should maintain a 10 minute window of historical CPU load information.
- The front-end application should alert the user to high CPU load.
- The front-end application should alert the user when CPU load has recovered.
Architecture
State is managed by the module store. The state consists of the following:
- avarageLoad10MinWindow - Events array of the past 10 minutes. Each event consists of its time and avarage CPU load value.
- currentAvarageLoad - Numeric value of the latest avarage CPU load.
- cpuLoadEvent - Array containing High CPU load events. Each event consists of its start & end time, and type - either high load or recovery.
The store has the following API:
- getState - Returns a copy of current module state.
- dispatch - Dispatches a change type and payload, and changes the state accordingly.
- subscribe - Allows subscribing to state changes, returns an unsubscribe method.
The state is displayed by 3 UI components:
- CPUAvarageLoad - displays current avarage as it is kept in the state.
- CPULoadEventsInfo - displays counts of high CPU load & recovery events.
- LoadTimeWindow - displays an SVG graph of the avarage load changes in the past 10 minutes. The graph is colored according to events. When rendered or updated, we iterate for each data point through the CPU load events, and color the relevant time slot accordingly. The iteration through the events is kept under O(1), since we have at most 4 CPU load events.
UI
Page is built with the following components:
Page
Header
Grid-Container
CPU-Avarage-Load
CPU-Load-Events-Info
Load-Time-Window
Future Application Improvements There are definitely some improvements that can be done for a production version:
- WebSocket is using ws protocol which is not secure. Production version requires an SSL certificate to use wss protocol for the socket.
- The chart can display a tooltip with values on hover, which will make it easier to see the accurate value.
- More testing - using e2e tests or purhaps jest snapshots, to make sure the UI doesn't break on changes.
- Store state can use models in case of a more complicated data structure.
- Store can use state reducers when maintaining a more complicated state.
- Production stack should also minify the files.
- Testing on non-linux environment - I only tested the application on my own machine, although I added the package
loadavg-windows
that should add support for window os. - Handling 'sleep' time - the application could notify the server if the app tab is not active, and then the communication between FE and BE can 'go to sleep' while data is accumelated on the server side, that will send it once the application is active again.
- CSS Grid display on IE only has partial support with
-ms-
prefix, which I didn't use. A fallback IE CSS should be added on production.
Stack
Babel+Webpack for compiling and serving the page. Jest for testing.
Run yarn start
in order start the express server. Load http://localhost:3000/
for the page.
Run yarn test
in order to run the jest tests.
Hope you enjoy this amazing challenge implementaion! :)