System requirements
Functional:
- System must keep track of total number of available parking spots and only allow users entry if parking is available
- On entry, the system must record the users license plate and entry timestamp
- On exit, the system must generate parking payment
- If user successfully makes payment, the system will allow the user to exit
- The system must support admin access to configure pricing, total number of parking spots, etc.
Non-Functional:
- Highly available
- Strong data consistency
Capacity estimation
totalStorage per lot = 1000 lots * 20B = 20KB
support approx 100K parking lots
total Storage = 100K * 20KB = 2GB
total requests per day: 1200 * 100K = 120M
write:read ratio is going to be 1:1 as every time a user enters, there will be a read and a write and same for exit.
API design
parking service:
entry(licensePlate, entryTimestamp, lotId)
exit(licensePlate, exitTimestamp, lotId)
configuration service:
addParkingLot(userId, price, capacity)
updateParkingLot(userId, lotId, price, capacity)
deleteParkingLot(userId, lotId)
Database design
Vehicle
licensePlate (PK) -> the license plate of the user which will be scanned at the entry gate
entryTimestamp -> the time at which the user has entered the parking lot
lotId (FK) -> the parking lot that the user has entered
Parking Lot
lotId (PK) -> unique identifier for the parking lot
ownerId (FK) -> owner of parking lot
price -> cost of parking per hour
capacity -> how many lots the parking lot supports
Lot Owner
ownerId (PK) -> id of owner
username -> username of owner
email -> email of owner
passwordHash -> password of owner account
High-level design
- We will have a load balancer to handle requests coming into the system
- We will have a parking lot management service that will route requests to the appropriate service
- We will have a parking service that will be a rest API to handle entry or exit requests
- We will have a configuration service limited to admin users to update parking lot configuration
- We will have a relational database as we will want to keep track of the count of available lots, relationships between lot owners and their lots, and vehicles
Request flows
- If a user approaches the entry gate (client), this will make a request to the parking service, this will first make a call to the database to get lot details then write the vehicle details to the database
- If a user approaches the exit gate (client), this will make a request to the parking service, then the parking service will make a call to the database to get the vehicle details and lot details, and generate the payment.
- If an admin user logs into the system, this will make a request to the configuration service, and the service will write the parking lot details to the database.
Detailed component design
- The parking service will be responsible for handling entry and exit processes:
- For entry, the service will retrieve the total count of available spots and total occupied spots from the database. If there are spots available, the service will write the vehicle details to the database.
- For exit, the service will retrieve the vehicle details based on the scanned license plate, calculate the number of hours parked based on the entryTimestamp property, and generate the total payment amount (hours * price).
- The configuration service will require the user to be authenticated via login (not included in scope), it will first check in the database if the userId matches the ownerId of the lot being updated or deleted, and update the details in the database if it matches. If it is a new parking lot, it will simply write the new parking lot details to the database.
Trade offs/Tech choices
- The choice to use a relational database will allow us to maintain strong consistency as it supports ACID properties. Any modifications to the parking lot should be up to date for any other services trying to grant entry to a user. This may cause a drawback in write performance.
Failure scenarios/bottlenecks
- The system may face a bottleneck on the relational database as all requests are being made to the database from each service.
- The database may be a single point of failure.
Future improvements
- We can shard the database by range of lotIds to distribute the load on the database.
- We can replicate the database to avoid single point of failure.