Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
Client can use REST API to send request:
POST v1/findDriver body: {origin: (latitude, longitude), destination: (latitude, longitude), timestamp: time}
Driver can use REST API to accept request:
POST v1/acceptOrder body: {order_id: id, rider: user_id, origin, destination, timestamp}
Driver can use WebSocket to upload position, because it needs to upload position every 5 seconds, using WebSocket has less overhead.
Request body: {driver: user_id, position: (latitude, longitude), timestamp}
Rider send request with origin and destination to the system, system store the ride information and status in a SQL database, because we need ACID. The ride table schema looks like:
{
ride_id: int
rider: user_id
driver: driver_id
origin: (latitude, longitude)
destination: (latitude, longitude)
status: {pending, assigned, transportation, done, cancelled}
timestamp: time
}
Transport service send a RPC call to match service to find drivers based on arrival ETA. Match service retrieve all available drivers around the origin and sort by ETA from short to long. Match service send a ride request to the first driver, if the driver rejected the request, the service send the request to the second driver, etc. until on driver accepted the order. Once the driver accepted the order, the match service updates the ride table, e.g. fill the driver column, change the status. Duplicate acceptance will be rejected because of the ride table has already a driver assigned.
Driver use WebSocket to connect with location service and upload its position every 5 seconds, the payload is:
{latitude, longitude, timestamp}
The location service update the record in the in-memory database:
dirver_id -> {latitude, longitude, timestamp}
Once a driver accepted the order, the location service push the driver's location to rider via WebSocket connection.
If the driver is offline then the record will be removed from the in-memory database. So match service can use the record to retrieve online drivers.
The in-memory database is replicated into 3 pieces, which increase availability.
API gateway is to do authentication, load balance.
We can put a queue between transport service and match service, so that we can support high volume traffic. When the request from transport service is large, we can increase the instance number of match service.
Define the data model. Identify the main entities, their attributes, and relationships. Consider the choice of database type (SQL vs NoSQL) and justify your decision based on access patterns...