Argomento precedente: Case study 13: gestione del gruppo di componenti dinamicoArgomento successivo: Esempi di scrittura di business logic efficace


Case study 14: gestione clock di controllo del tempo

Il modello di progettazione descritto in questa sezione è adatto quando il risultato richiesto è una funzione di un periodo di tempo trascorso tra eventi, ad esempio:

Per accumulare tempo, è necessario assegnare una variabile in cui è possibile accumulare tempo (in secondi) e implementare una funzione che controlli le condizioni e il tempo accumulato dall'ultimo aggiornamento avvenuto. Questa funzione viene quindi eseguita per ogni evento ricevuto dalla formula.

La seguente illustrazione raffigura il clock di controllo del tempo.

La variabile LastUpdateTime memorizza l'ultima volta in cui è stato eseguito l'aggiornamento, a prescindere se il contatore di tempo fosse aggiornato oppure no. La funzione contiene la condizione che determina se è necessario aggiornare o accumulare tempo. Ad esempio, il tempo non deve essere considerato se supera il periodo di applicazione, lo stato del sistema è Non attivo o un incidente è nello stato in sospeso.

Sebbene la situazione delineata in questo caso spesso utilizza la funzione Tools.NetTime() per calcolare la durata, potrebbero esservi casi in cui è preferibile utilizzare la funzione VB standard DateDiff().

La funzione Tools.NetTime comporta un sovraccarico di verifica del periodo di applicazione ogni volta che viene utilizzata. Si consiglia di evitare l'uso di NetTime nelle procedure degli eventi di dati in quanto tali procedure sono invocate per ogni nuovo evento in arrivo e, pertanto, invocano la chiamata NetTime. Se il proprio periodo di applicazione è 24 ore per 7 giorni, si consiglia di utilizzare la funzione DateDiff per evitare il sovraccarico di verifica del periodo di applicazione.

Esempio 1:

La seguente routine dei contatori di aggiornamento accumula il periodo di tempo totale nella variabile PeriodNetTime. In AvailabilityTime la routine accumula il tempo in cui lo stato di sistema era Attivo, indicando che il sistema era disponibile.

L'oggetto Tools contiene il metodo NetTime, NetTime(beginTime, endTime)0. Questo metodo restituisce il numero di secondi tra beginTime ed endTime che rientrano nel periodo di applicazione della metrica corrente. Qualsiasi intervallo di tempo tra queste due variabili è parte di un periodo di applicazione escluso, perciò, è utilizzato molto comunemente per i calcoli di durata in cui viene impiegato un periodo di applicazione. Ad esempio: per i ticket con priorità 1 risolti in quattro ore lavorative, anche se un ticket veniva emesso alla fine di un giorno lavorativo e poteva non essere risolto fino al giorno successivo, è ancora incluso nello SLA per via delle ore del periodo di applicazione escluse.

Sub UpdateCounters (time)
   PeriodNetTime = PeriodNetTime + tools.NetTime (LastUpdateTime, time)
   If SystemStatus = UP Then
      AvailabilityTime = AvailabilityTime + tools.NetTime (LastUpdateTime, time)
   End If
   LastUpdateTime = time
End Sub

Esempio 2:

L'esempio seguente calcola la disponibilità dell'applicazione tramite la gestione degli eventi Attivo e Non attivo di diversi componenti critici, nonché gli eventi di manutenzione di tali componenti. Se tutti i componenti sono in manutenzione, il tempo non viene considerato come tempo di disponibilità prevista.

La subroutine UpdateCounters anticipa i contatori di tempo quando necessario e viene eseguita con ogni evento ricevuto per la formula (Evento di dati non elaborati/Evento del motore). Inoltre, aggiorna il tempo disponibile previsto nei casi in cui il tempo è compreso entro il periodo di applicazione e i componenti non sono all'interno del periodo di inattività pianificato. La formula aggiorna il tempo di disponibilità corrente solo quando dispone anche dello stato di sistema Attivo.

DateDiff è una funzione VB standard che restituisce il tempo tra due date, ma non esclude eventuali informazioni sul periodo di applicazione.

'Forzare la dichiarazione di variabile
Option Explicit

'Variabili globali
Dim ExpectedAvailabilityTime
Dim ActualAvailabilityTime
Dim LastUpdateTime
Dim AvailabilityIndicators
Dim MonitoredComponents
Dim DowntimeStatuses

'Mappare la creazione di oggetti
Set AvailabilityIndicators=CreateObject("SlalomMap.Map")
Set MonitoredComponents=CreateObject("SlalomMap.Map")
Set DowntimeStatuses=CreateObject("SlalomMap.Map")

'Dopo il caricamento e quando si verifica una modifica all'infrastruttura
Sub OnRegistration(dispatcher)
   dispatcher.RegisterByResourceGroup "OnComponentDownEvent","Component Down","Application Components"
   dispatcher.RegisterByResourceGroup "OnComponentUpEvent","Component Up","Application Components"
   dispatcher.RegisterByResourceGroup "OnMaintenanceStartEvent","Maintenance Start","Application Components"
   dispatcher.RegisterByResourceGroup "OnMaintenanceEndEvent","Maintenance End","Application Components"
   UpdateCounters Context.RegistrationTime

   Dim AllocatedComponents
   Set AllocatedComponents = Context.ResourcesOfResourceGroup("Application Components")

   'assicurarsi che la formula controlli solo tutte le risorse pertinenti
   UpdateMonitoredComponents AllocatedComponents
End Sub

Sub OnLoad(time)
   'Quando il sistema è attivo per la prima volta, presupporre disponibilità OK
   LastUpdateTime = time
End Sub

Sub OnPeriodStart(time)
   'inizializzazione contatori per rieseguire il calcolo periodico
   ExpectedAvailabilityTime = 0
   ActualAvailabilityTime = 0
End Sub

Sub OnTimeslotEnter(time)
   UpdateCounters time
End Sub

Sub OnTimeslotExit(time)
   UpdateCounters time
End Sub

Sub OnComponentDownEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'scrivere lo stato di disponibilità della risorsa segnalata
   AvailabilityIndicators(eventDetails.ResourceId) = _
      AvailabilityIndicators(eventDetails.ResourceId)+1
End Sub

Sub OnComponentUpEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'scrivere lo stato di disponibilità della risorsa segnalata
   AvailabilityIndicators(eventDetails.ResourceId)= _
      AvailabilityIndicators(eventDetails.ResourceId)-1
End Sub

Sub OnMaintenanceStartEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'scrivere lo stato di disponibilità della risorsa segnalata
   DowntimeStatuses(eventDetails.ResourceId)= _
      DowntimeStatuses(eventDetails.ResourceId)+1
End Sub

Sub OnMaintenanceEndEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'scrivere lo stato di disponibilità della risorsa segnalata
   DowntimeStatuses(eventDetails.ResourceId)= _
      DowntimeStatuses(eventDetails.ResourceId)-1
End Sub

Sub OnPeriodEnd(time,isComplete)
   UpdateCounters time
End Sub

Function Result
   If ExpectedAvailabilityTime <> 0 Then
      Result = 100 * (ActualAvailabilityTime / ExpectedAvailabilityTime)
   Else
      Result = Null
   End If
End Function

Sub UpdateCounters(time)
   If Context.IsWithinTimeslot And Not AllComponentsAreInPlannedDowntime Then
      'aggiornare il contatore di secondi nel periodo di tempo (in caso di disponibilità prevista)
      ExpectedAvailabilityTime = ExpectedAvailabilityTime + DateDiff("s",LastUpdateTime,time)
      If SystemIsAvailable Then
         'aggiornare il contatore di secondi di disponibilità
         ActualAvailabilityTime = ActualAvailabilityTime + DateDiff("s",LastUpdateTime,time)
      End If
   End If
   LastUpdateTime=time
End Sub

Sub UpdateMonitoredComponents(allocatedComponents)
   Dim Component
   'aggiungere alla mappa dei componenti monitorati tutti i nuovi componenti da monitorare
   For Each Component In allocatedComponents
      If Not MonitoredComponents.Exist(Component) Then
         MonitoredComponents(Component) = Component
         AvailabilityIndicators(Component) = 0
         DowntimeStatuses(Component) = 0
      End If
   Avanti

   'rimuovere dalla mappa dei componenti monitorati tutti i componenti non più pertinenti
   For Each Component In MonitoredComponents
      If Not allocatedComponents.Exist(Component) Then
         MonitoredComponents.Erase Component
         AvailabilityIndicators.Erase Component
         DowntimeStatuses.Erase Component
      End If
   Avanti
End Sub

Function SystemIsAvailable
   Dim SystemAvailability
   SystemAvailability = True

   Dim Component
   Dim ComponentAvailability
   For Each Component In MonitoredComponents
      ComponentAvailability = AvailabilityIndicators(Component) = 0 _
         Or DowntimeStatuses(Component) > 0
      'la disponibilità di sistema è valutata con la disponibilità
      SystemAvailability = SystemAvailability And ComponentAvailability
   Avanti
   SystemIsAvailable = SystemAvailability
End Function

Function AllComponentsAreInPlannedDowntime
   Dim ComponentsInPlannedDowntime
   ComponentsInPlannedDowntime = 0
   Dim Component
   For Each Component In MonitoredComponents
      If DowntimeStatuses(Component) > 0 Then
         ComponentsInPlannedDowntime = ComponentsInPlannedDowntime + 1
      End If
   Avanti

   If ComponentsInPlannedDowntime = MonitoredComponents.Count Then
      AllComponentsAreInPlannedDowntime = True
   Else
      AllComponentsAreInPlannedDowntime = False
   End If
End Function