There are several “Design Patterns” which can be used in many business logics. Those design patterns are tested, and using them when applicable can save a lot of time and in most cases create more efficient business logic. This case study focuses on one such design pattern.
Update Counters Design Pattern
This design pattern is useful, in almost every business logic, which is intended to measure time between certain events. Examples of such business logics are business logics for measuring availability, downtime, mean time between failures, mean time to restore, average response time, average resolution time, percent of components with availability less then X, number of cases not resolved on time, etc.
The common part for all those business logics is that their result depends on the timestamp of various events they receive.
A rule of thumb for deciding if your business logic can benefit from this design pattern would be: if your business logics depends on the timestamp of the various events it receives it most probably should use this design pattern.
Skeleton of this Design Pattern
The code of a business logic that utilizes this pattern can be split into two parts: a framework and an implementation. The framework contains code which in most cases is fixed and does not change for the various business logics. This part is the same for calculation of availability and number of tickets not resolved on time. The implementation contains code which is specific to each business logic.
It is recommended to put those two parts of the code into separate business logic modules and reuse the module of the framework in different metrics.
Here is the code of the framework:
Dim g_PrevEventTimestamp
Sub OnLoad(time)
g_PrevEventTimestamp = time
InitializeStatusVariables
End Sub
Sub OnRegistration(Dispatcher)
' If there is a separate copy of status variables
' for each registered resource depend on the registered
' resources you should set initial values to the
' status variables of the newly added resources here
End Sub
Sub OnPeriodStart(time)
InitializeCounters
End Sub
Sub OnPeriodEnd(time, completePeriod)
HandleEvent (time)
End Sub
Sub OnTimeslotEnter(time)
HandleEvent (time)
End Sub
Sub OnTimeslotExit(time)
HandleEvent (time)
End Sub
Function Result()
Result = CalculateResult()
End Function
Sub HandleEvent(Time)
Dim diff
diff = TimeDiff( "s",Time,g_PrevEventTimestamp)
UpdateCounters(diff)
g_PrevEventTimestamp = Time
End Sub
Here is a skeleton of the implementation module:
' Define your status variables here. This can be one
' simple global variable or many complex global variables
' depending on the business logic
Dim g_StatusVar_1, g_StatusVar_2, ... ,g_StatusVar_n
' Define your counters here.
' This can be one simple global variable or many
' complex global variables depending on the business logic
Dim g_Counter_1, g_Counter_2, ... , g_Counter_n
Sub InitializeStatusVariables ()
' Set initial values to the various status variables
End Sub
Sub InitializeCounters ()
' Set initial values to the various counters
g_Counter_1 = 0
g_Counter_2 = 0
'…
g_Counter_n = 0
End Sub
Function CalculateResult ()
' Calculate the result. The result should depend on
' the values of the counters. It should not depend on
' the value of the status variables. It should not
' change the values of the counters or the status
' variables
End Function
Sub UpdateStatus(method, eventDetails)
' Update the value of the status variables based on
' the parameters (and posibly on the old value of the
' status variables)
End Sub
Sub UpdateCounters(diff)
' Update the values of the counters based on their
' previous value, on the value of the status variables
' and on the value of the diff parameter.
' In many cases this calculation is also based on the
' value of Context.IsWithinTimeslot
End Sub
Sub OnEvent_1(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnEvent_1”,eventDetails)
End Sub
Sub OnEvent_2(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnEvent_2”,eventDetails)
End Sub
'...
Sub OnEvent_n(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnEvent_n”,eventDetails)
End Sub
To better explain this design pattern, here is an example of the implementation of this pattern for calculating availability. This example assumes there are events for UP and DOWN that are handled by two separate event handlers in the business logic. The availability is defined as the percent of time during which the system is up from the total time in the timeslot. The status of the system is assumed to be the status of the last event received (UP or DOWN).
Here is the code of the implementation (the code of the framework is not changed):
' Status variable
Dim g_Status
' Counters.
Dim g_UpTime, g_TotalTime
Sub InitializeStatusVariables ()
G_Status = “UP”
End Sub
Sub InitializeCounters ()
g_UpTime = 0
g_TotalTime = 0
End Sub
Function CalculateResult ()
If g_TotalTime = 0 Then
CalculateResult = Null
Else
CalculateResult = g_UpTime/g_TotalTime*100
End If
End Function
Sub UpdateStatus(method, eventDetails)
If method = “OnUP” Then
G_Status = “UP”
Else
G_Status = “DOWN”
End If
End Sub
Sub UpdateCounters(diff)
If Context.IsWithinTimeslot Then
G_TotalTime = g_TotalTime + diff
If g_Status = “UP” Then
G_UpTime = g_UpTime + diff
End If
End If
End Sub
Sub OnUp(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnUp”,eventDetails)
End Sub
Sub OnDown(eventDetails)
HandleEvent (eventDetails.Time)
UpdateStatus(“OnDown”,eventDetails)
End Sub
There are several variations on this pattern. One of the most common variations is when a separate time counter should be maintained for different entities. For example, when we measure solution time, a separate counter should be maintained for each open ticket. In this case when handling an event which is relevant only to one ticket it is more efficient to update only the counter of that ticket. When a common event is handled (such as OnPeriodEnd or OnTimeslotEnter) the counters of all tickets should be updated.
Note: This variation of the pattern requires maintaining a separate copy of the g_PrevEventTimestamp global variable for each ticket.
Some good examples of the usage of this pattern can be seen in our predefined content. Keep in mind though that this pattern is used a bit differently in the predefined content and the separation between the framework and the implementation is not so obvious there.
|
Copyright © 2013 CA.
All rights reserved.
|
|