System requirements
Functional:
- Book a parking spot
- Allocate free parking spot
- Payment processing at reservation
- Refund if booking is canceled
- Find disabled friendly spot
- Users can review their payment history
Non-Functional:
- Response time < 200ms for booking
- Payment done under 2s
- Scability to handle peak of traffic during events and or holidays
- Payment transactions have to be secure
- Users must be strongly authenticated
- All activity must be logged
Capacity estimation
- About 1000 parkings lots
- Reservations requests:
- 10-hours window of activity
- About 200K reservations a day (~6 requests/s)
- 2x-3x increase during events or holidays so 500K (~14 requests/s)
API design
list
string GetParkingLotDetails(int parkingLotId)
int FindFreeParkingSpace(int parkingLotId, bool disabledFriendly)
float calculatePrice(int parkingLotId, datetime start, datetime end)
int BookParkingLot(int parkingSpaceId, datetime start, datetime end)
string GetReservationDetails(int reservationId)
bool CancelBooking(int reservationId)
Database design
- ParkingLots
- [PK] int id
- string address
- float pricing
- ParkingSpaces
- [PK] int id
- [FK] int parkingLotId
- [FK] int reservationId
- bool isDisabledFriendly
- Reservations
- [PK] int id
- [FK] int parkingSpaceId
- [FK] int paymentId
- [FK] int userId
- datetime reservationDate
- datetime start
- datetime end
- Users
- [PK] int id
- string email
- string password
- string firstName
- string lastName
- datetime registrationDate
- datetime lastlogindate
- Payments
- [PK] int Id
- int amount
- string paymentsDetails
High-level design
- Load-balancer to distribute evenly the requests among the application servers
- Database with strong consistency (RDBMS)
- Usage of transactions for reservations to handle concurrency scenarios
- Active-active topology to handle failures
- A relationnal database should be able to handle the planned 6-14 requests/s
- Parking lot details can be cached as they don't change often
- Logging database use a append-only model
Request flows
- User login to the reservation platform
- User list different parking spaces
- Reservations:
- Ask for a free parking space
- Try to book the free parking space
- Pay for the reservation
- Cancellation:
- Delete the reservation
- Refund the user
Detailed component design
The platform can authenticate by a third-party provider using the OAuth protocol
We need a distributed lock mechanism to handle possible concurrent reservation of the same parking space
Possible solutions:
- Having a flag in the database with serializable isolation level
- Use datastore like Redis that serialize requests (possibilty to have a TTL so we can have a maximum duration for reservation session)
Trade offs/Tech choices
A RDBMS is used to handle well the transactions but it won't scale very well if we need to support much more requests
Failure scenarios/bottlenecks
The active-active topology can handle the failure of one of the database node
Future improvements
Possibility to handle different vehicules types (motorbike, SUV, camping car etc.)