Detailed Component Design
Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.
Cache
We will be using Redis Cache to provide caching support to this application. Following are the key concepts
- Cache invalidation
- Every type of data is allocated a Time to live so that we avoid stale data.
- When data such as vital stats or workout data is being updated, we look up that key in cache and invalidate it as it's being updated and the old data is no longer valid
- Cache miss
- For the get data, we will attempt to read from cache and if there is a miss we will retrive and update in our cache. Following data will be read from cache -> vitals history, workout history, exercise list.
Database
We will be using a MariaDB or MySQL database or any relational database as we don't have any unstructured data. We will be maintaining 3 nodes with 2 nodes replication.
We will shard on the basis of user id to ensure even distribution. Distribution of keys on nodes will be done using consistent hashing to ensure that when nodes are added or removed, it's done with minimal impact
Scenarios
- What happens when user tries to upload activity twice
- Every activity has an idempotency key consisting of the start time and the user id. Since we cannot start two activities at the same time, this idempotency key should be good enough to identify that workout and remove the duplicates. Along with the idempotency key, we also send the timestamp when the upload is attempted. We take the more recent timestamp. Reason is , since the data is originating from the user's mobile, the more recent one needs to be picked
- How to handle large uploads?
- We will ensure that the client does multiple patch requests. Data for a single exercise should not be greater than a few KBs
- We will also do rate limiting at the API gateway to ensure that no rogue upload is allowed inside
- In case of a large workout data, the client will be syncing data for each exercise and since that data is large, there is no lag or blocking at the client side.
- Once the data is pushed, it's an asynchronous request with a call back that is invoked once the data is saved. So there is no waiting on the client side.
- Once the callback is invoked, that exercise is shown in a different colour or some other indication to convey to the user that data is synced
- How to handle out of order data?
- In case of a large workout data, we breakdown the data according to exercises and it's sent separately for asynchronous processing. However, this creates a problem as they can be processed out of order
- To handle this, each exercise will have a start time and end time. This will be used by the client when the data is to be displayed again.
This app does not support cycling based workouts