Scalability
System should work the same for small parking lots and large parking lots. The only scalable sections of this system would have to be in the number of requests that it might encounter during peak times of the day where the load balancer may need to be leveraged in order to distribute traffic amongst pods correctly.
Performance
Assuming thousands of cars enter and leave a specified parking lot in a given day, system should be capable of reading and writing approximately the same amount in a relatively timely fashion.
Traffic should be directed in a manner that drivers are able to encounter the open spaces and when exiting have a path that leads them relatively quickly to an exit.
Reliability
System CANNOT lose track of vehicles and current space occupation statuses and that can result in more vehicles being permitted than possible. As such it is important that the system be Consistent and Available through its lifetime. Partition Tolerance is a little less important as the relative size of the amount of information stored is typically stable for the most part outside of tracking perhaps aggregation data such as the number of vehicles recorded entering and leaving within a given period of time.
Storage
A SQL database might not be a bad option for this given that its important we track vehicle ids, entry times, exit times and the like fairly consistently.
Backup and Recovery
Very critical that there be redundancy of such information within this system. A hot swap may be necessary with a few other redundant systems in the backlog in order to ensure that data is not lost.
Monitoring and Logging
Monitoring and logging within this system can be done in a variety of ways, first is the entry and exit locations that vehicles leverage, the second is time spent within the parking space, another important piece of data to track may perhaps be the number of vehicles left over night or entered/exited throughout a given day and more. This information will typically be collected alongside the typical primary functionalities of this system and stored in a relevant location where it can be further studied if needed.
Security
One of this most important aspects is that we do not want vehicles that are not permitted to access said parking space or individuals without the proper credentials to leave. As such having some form of identification for drivers to leverage when entering/leaving is critical in order to ensure unauthorized departure does not take place. In addition to this, if a payment system is introduced, encryption of said data is of critical importance to validate payment data, keep customer data safe and deter malicious actors from hijacking this information and either capturing customer data or stealing/modifying our own systems data.
On a typical end, parking lots tend to have upwards of several thousand slots available with a variety of different entrances and exits where signs keep track of the available slots in different zones. As such, the number of requests that come in by the second for a given parking lot could be in the dozens depending on the structure of said parking lot. Assuming this system is meant for a single parking lot, the system should be prepared to handle this many requests at the very least.
On the API side of things, having websockets may in fact be helpful to open two way communication between customer facing systems and the backend. This way updates can quickly be pushed from our system from one location (ie our backend) to all the front end systems at once whereas the front end systems could pass down a variety of single events down which can be queue and then processed accordingly split between entry and exit events.
Because JSON can be leveraged in order to send data and accept data, we can use predetermined schemas in order to identify our entrance and exit events as follows:
Entrance
{
vehicle_id: "",
vehicle_type: "",
date_time_arrival: "",
}
Exit:
{
vehicle_id: "",
date_time_departure: ""
}
This exit event would also be followed by a slot update event which would correct the number of parking spaces marketed to incoming attendees by 1 across the board where the "client" end would be awaiting the incoming event.
The database as it is simple in nature should simply in my opinion be in the form of a my SQL database for a few reasons. The first of these being the fact because the number of spaces within the parking lot is limited, there is a maximum amount of space the system will handle meaning that additional partitions outside of the original will not be required for the vehicle data that we would be recording through the enter and exit events taking place.
The second reason is because we require changes made to the database to be consistent and reliable. If an enter event occurs and database isn't correctly updated, that event must retry until it succeeds as there overall number of slots in the parking lot will be reducing by 1.
The third reason is due to the need for availability. If the system goes down at any point, we will not be able to send events to verify the entrance/exit of vehicles, nor will we be able accurately mark the space available in the parking lot that is unoccupied.
The primary table within the database would be in the following structure. Obviously this would be in a normalized structure as the redundancy from a denormalized itemization would be redundant and unnecessary:
Vehicle:
id: UUID
arrival_time: datetime
departure_time: datetime
vehicle_type
Lot_capacity:
lot_type: String
vehicle_type: String
capacity: integer
In the case that the lot is full, then the system would no longer accept new entry events until, slots have been freed up as would be recorded via an exit event.
From a high-level, we can view each enter/exit gate point as a supposed "client" from which our flows can occur with perhaps a secondary client being a display board where the number of slots and their types can be updated based on the exit events that take place and are pushed out to.
Once
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
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...
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?