System requirements
Functional:
- Number of spots in the parking lot
- Location of garage, garage id
- Size of vehicle (small, large)
Non-Functional:
- I initially thought SQL however if we scale this application to millions of users especially based on geolocation, we quickly begin to run into the problem of scaling data. In this case we use a NoSQL db like mongodb because it allows a flexible schema (JSON format) and has a scalable architecture since it supports sharding which partitions data across different servers. It also has built in geospatial indexing to making queries more efficient based on location
Capacity estimation
Millions of daily active users due to the app being made to scale worldwide.
API design
isLotFull(lotId) -> get request to check if the selected lot is full
getAvailableSpots(lotId) -> get request will search a parking lot by its levels to display exactly which spots in the garage are available
reserveSpot(lotId,timeStart,timeEnd,userId,vehicleId)
timeTillKicked(userid,lotid,timeStart) -> This will refund a user if they have booked a spot but do not show up on time
Database design
User {
userId: int,
name: string,
vehicles: Vehicle[],
email: string,
phone: string,
}
VehicleType {
large:'large',
small:'small'
}
Vehicle {
vehicleId: int,
model: string,
make: string,
licensePlate: string,
type: VehicleType
}
Spot {
spotId:int,
parkingLevelId: int,
isAvailable: bool,
timeStart: datetime,
timeEnd: datetime,
databaseLockTimeStart datetime
}
ParkingLevel {
levelId: int,
parkingLotId: int,
spotStatus: Spot[]
}
ParkingLot {
lotId: int,
city: string,
longitude: float,
latitude: float,
totalSpots:int,
levels: Level[]
}
Reservation {
reservationId:int
currentUser: User
timeStart: datetime
timeEnd: datetime
spotTaken: Spot
}
Payment {
paymentId: int,
user: User
vehicle: Vehicle,
creditCard: string
}
High-level design
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
User will visit the app and be routed to the appropriate version of the app based on geolocation. They will input their garage Id and then the server will check if the garage has any spots. If it does, they will then be shown the first available spot there is, at this point a database lock will be placed on this specific spotId preventing someone else from trying to access it and a timer would begin. If the user takes too long the app will display a message saying they took too long and redirect them to the home screen. If the user decides to take the spot then a payment service such as Stripe will handle their payment. Then the database will be updated with the updated spot information. A timer will be activated from the moment the user's timeStart value and if they do not visit their spot within lets say 15 minutes, then they will be refunded a portion of their allotted time and the spot will open up again.
Request flows
- user creates a request to the api and the server's load balancer will route this request to the appropriate database shard based on geolocation.
- This request will be handled by the server taking into account parking lot capacity, user vehicle and other information input by the user and cache this information
- If the user purchases a spot, this payment will be handled by a payment service such as stripe and give the user a choice of few different spots in the parking garage based on success of the payment
- The server will utilize optimistic concurrency control to prevent data from being stale
- The information will then be written to the database
Detailed component design
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Trade offs/Tech choices
Trade off availability for consistency and partition tolerance because we want something that is highly consistent so nobody views stale data for the available spots and partition tolerance so we can
Failure scenarios/bottlenecks
- celebrity problem where one geolocation may experience lots of traffic especially if there is an event like a concert with thousands of people visiting a few garages
- Since we traded off availability, the design won't be prioritized to be highly available
Future improvements
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?