Skip to content

Can you take a cab, please? Or I will shoot you!!!

Notifications You must be signed in to change notification settings

legitYosal/cab-please

Repository files navigation

Introduction

This project tries to create a solution for high load demand surges in a taxi as a service provider platform like uber.
This is a proof of concept and is not intended to be used in production.

How to run and use the project

I have dockerized the project and you can run it with the following commands(you must have installed git, docker and docker-compose before running these commands):

$ git clone [email protected]:usefss/cab-please.git
$ cd cab-please
$ docker-compose build
# copy .env.example to .env in each service
$ docker-compose up -d --scale decreaser=4

Now to interact with the identity service and create a new user and obtain tokens you can use the swagger ui exposed at this url.
And you can interact with the passenger service to request a ride and see the calculated surge rates, using the swagger ui exposed at this url(Please send real longitude and latitude, I forgot to put validation).
And finally as an admin user you can interact with the surge rating API, uing the swagger ui exposed at this url.

Software architecture

The mind map and the concepts I have put together to create the finanl output.

We start from the simplest possible thing, someone needs a cab and someone is a cab. There are many many people demanding a cab and many cabs offering their services. We want a very very very minimal and simple solution, ignoring the distances, destination, user experience and other things.

Here I have demonstrated a normal not-realtime HTTP based process for requesting a cab.

simple request response

Probably, when the cab reaches the pessanger, the system will set the demand status to in-journey and when they reach the destination, the system will set the demand status to completed, we do not need to achieve these at this time.
Infact we are going to investigate just step 1, and step 2. The problem is that sometimes demand is so much higher than the number of cabs available. for example we can only service around 100 people in a hour, but demand is beyond that number, also we can conclude that if we are that much popular and there are so much demands, we can somehow make more money.
The proposed solution to this problem is getting a higher fee for the exact demand, with the exact joureny, so this will lead to less people using our service in short terms, hence flattening the surge in demands in this short time peroid, also it will cause more caps register into our product because of high wage in long terms.

How to implement it?
We just need to check how many demands are created in last one hour, and if the number is higher than the threshold, we will multiply the journey cost by the rate specified.
It is clear that executing a query for each demand to calculate the surge rate, is not practical, so I thought of two approaches:

  1. Cache the number of demands with a short time life span, for example we query the database and cache into redis for one minute, and surge service calculates the rating from this value, after one minute it will be refreshed hence old demands will be removed and new ones will be added, one problems is that this is not so much realtime, if we have a surge of demands in under one minute, we will not be able to detect it.
  2. More realtime aproach, we can cach the number of demands in redis on service startup, and each new demand will increase the cach value by +1, and after one hour, we will decrease the cach value by -1, hence the value is realtime and surge rating is calculated very precisely.

Aproach one doesn't requrie much resources, but aproach two uses a time queue to decrease the cached values, for example, if we have one milion demands in a time span of one hour(worst case scenario, not going to happen very soon), there will be almost one milion decrease by one after one hour messages in the queue, the worst possible thing can happen is that you will need about one or two extra GIGs of RAM.
A small note about the aproach two is that, because there maybe old messages on the queue, the worker that consumes the decrease messages must does the message only if it is created after the timestamp of the cached value, otherwise it will be ignored, to assure the consistency. And a similar condition is that the queue is not up running, so we have persisted numbers of demand counts in cache, so in later days we may reset the cache to zero in the early mornings...
Also we must check if one unique user is trying to create many demands in a short time, if so, we will not change the cached demand count, or we can rate limit a user or IP block him or her.

surge service basic

And we need a service to resolve the geographical location of the client into the real life district name or district id, so we are going to use open street map data, and nominatim api to obtain these information.
Also we need a user management service that will handle authentication of our clients.
The primary system design:

overal design

I had came up with an idea to change and manage surge ratings in a persistant and realtime way, admins can interact and change ratings using rest api, and with each change the system will push the change to the redis cache and the surge service will calculate the new ratings.
The final system design schema:

final design

Resources

Here are some usefull links:

About

Can you take a cab, please? Or I will shoot you!!!

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published