Imagine a scenario where records maintained in a database
need to be transitioned from one state to another i.e. the next higher state
based on how long those records have been in the current state. This is a common
scenario in trade settlement, customer service or ticketing systems where the
incidents are governed by strict SLAs such that the priority of the case goes
on increasing the longer the time it spends on a wait queue lying unattended.
Supposing you were to write a program where you would fetch
these records from the database and then check for each one of those records
how much more time is left before it needs to be escalated to the next higher
level. What would be the time interval at which you will fetch potentially
hundreds or thousands of records from the database and then go on checking for
each one of them whether to escalate it to next level or keep it in the same
state? The program will need to go on polling
the database at regular intervals. But what should be the interval at which
this poll should take place. Based on the number of records in the database
this can happen potentially at every second, which would be a huge overhead on
the system. Moreover by its very nature
polling is very inefficient. If we were to fix the polling interval at some
arbitrary value let’s say once every 15 secs, then we run the risk of delaying
the priority escalation by 15 secs and the system developed on this design cannot be called a real-time
system.
Is there a better way
around this that can avoid polling? Well of course there is, that’s why this
blog.
What I am proposing here is an algorithm that will find out
heuristically when the next record in the database is due for a state change. I
will explain this with an example. Let’s take a simple business case here, for
example a ticketing or incident management system, where once a ticket is
raised by an analyst its priority goes on increasing the longer it stays in the
queue unattended as below:
Ticket origination time + 8 hours - Low priority (4)
Ticket origination
time + 12 hours - Medium priority (3)
Ticket origination time + 16 hours - High priority (2)
Ticket origination time + 20 hours - Urgent priority (1)
The program implementing this would use the following
algorithm.
1. Start
2. From all the ticket records in the database, find
out the ticket(s) with the nearest interval of time (‘lt’) from now when the priority
escalation / state / level change is due.
3. Sleep
/ put the program on hold for ‘lt’
time units.
4. When the program wakes up after the sleep
interval ‘lt’, change the priority of
the record(s) for which it is now due.
5. Go to step 2.
Equivalent Java Code looks as below:
while
(true){
List<Ticket> ticketList =
ticketDAO.findNextPriorityChangeDue();
long nextEarliest =
ticketList.get( 0 ).getNextPriorityChangeDue();
long now =
System.currentTimeMillis();
if( nextEarliest >= now )
escalatePriority(
ticketList );
else
try {
Thread.sleep(
nextEarliest – now );
} catch ( InterruptedException
e ) {
escalatePriority(
ticketList );
}
}
With this algorithm you can see that there is neither a
fixed polling interval nor polling.
Whatever polling happens, it happens smartly. There is no need to supply
a hard coded or even configurable polling interval value. This is such a simple
solution and the program ‘learns’ about its next database trip on its own making
it heuristic in nature as the program goes on learning the next database
polling interval on its own without any user input.