How every Driver’s action is converted into a Reaction

Sartaj Singh
3 min readFeb 25, 2021

Tracking a driver’s location and his actions is a crucial part to every ride sharing platform. Every action that a driver takes, has an effect on the underlying system which is trying to find the best driver for an order. This essentially makes every driver action an event that might trigger multiple separate events in the system. Let’s take an example.

Charlie is a very moody driver. He just cancelled his last 4 orders after accepting, which in turn upset the customers, because they had to wait longer to get a driver and they were very eager to go home after work. Now to avoid such behaviour, we decide to not give any new orders to Charlie for the next 15 minutes, notify him about this penalty so that he doesn’t cancel too many orders again and update his statistics accordingly which might affect his overall earnings. This becomes necessary for a smooth user experience.

So if you see, every driver cancellation is an action/event here which can have multiple reactions some of which are:

  1. Don’t give him newer orders for the next X minutes as he is likely to cancel.
  2. Notify him about this time penalty.
  3. Update his overall statistics which might have further affects.

Now the question, how do we do this?

Answer: We have recently moved a part of our system to an Event Driven Architecture + Actor model which makes this fairly simple to do.

What is event driven architecture?

It is an architecture pattern which consists of production, detection, storage and consumption of events where an event could be defined as a state change. There are mainly three parts to it : the producer, the channel and the consumer.

[Image]

Why did we use Event Driven Architecture?

  • It helped support broadcast ability in our distributed system. Now a single service doesn’t have to talk to N other services when an event happens but instead it can just raise an event on a common channel and the concerned parties can listen to it and execute accordingly.
  • Addition of newer consumer components became very easy as no changes to the architecture is required but instead a new Actor that listens to an event solves the purpose.
  • It provides loose coupling within space, time and synchronisation, providing a scalable infrastructure for information exchange and distributed workflows.
  • Analysis and Retention of data becomes very easy as all the data can be dumped into a cold storage from the channel and you can even even write consumers to do analysis on the data at a central place without any further dependency.

Let’s see how Charlie cancelling an order would affect our event driven system:

[Diagram / this section is incomplete / Will add separately]

a. A stream of all the active drivers in an area where every location update is an event.

b. A stream of driver cancellations

Tools used:

  • we use Apache Kafka as our central channel where every producer raises an event and forgets about it.
  • we have extracted out a standard Clojure library and built a generic lambda actor which can be plugged in to subscribe to Kafka streams and do various kinds of activities on events may it be raising another event. Our Lambda team is working on automating and making our actors flexible where the concerned party doesn’t have to care about anything but writing a function to execute desired actions.

Some Caveats:

  • It becomes absolutely necessary to handle latencies in this system. You have to assume that an event may be delayed.
  • Automated retries while publishing to the central channel becomes a must as you also have to assume that there will be message publishing failures/timeouts and the channel may be unresponsive for a duration.
  • This architecture is very helpful when your data is short lived and is transient and doesn’t require immediate consistency.

--

--