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 GetParkingLots()

string GetParkingLotDetails(int parkingLotId)

int FindFreeParkingSpace(int parkingLotId, bool disabledFriendly)

int BookParkingLot(int parkingSpaceId, datetime start, datetime end)

string GetReservationDetails(int reservationId)

bool CancelBooking(int reservationId)




Database design

  • ParkingLots
    • [PK] int id
    • string address
  • 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
    • int durationInHours
  • Users
    • [PK] int id
    • string email
    • string password
    • 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

We need a distributed lock mechanism to handle possible concurrent reservation of the same parking space

Possible solutions:

  • Having a flag in the database
  • 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

What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?