Tópico anterior: Estudo de caso 13: Tratamento do grupo dinâmico do componente

Próximo tópico: Criando exemplos de lógica de negócios efetivas

Estudo de caso 14: Controle do relógio de acumulação de tempo

O padrão de design descrito nesta seção é adequado sempre que o resultado obrigatório for uma função de um período que tenha expirado entre eventos, por exemplo:

Para acumular tempo, é necessário atribuir uma variável na qual o tempo pode ser acumulado (em segundos) e implementar uma função que verifica as condições e o tempo acumulado desde a hora da última atualização transcorrida. Esta função é executada para cada evento recebido na fórmula.

A figura a seguir demonstra o relógio que trata do acúmulo de tempo.

A variável LastUpdateTime armazena a última hora em que a atualização foi executada, independentemente se o contador de tempo foi atualizado ou não. A função possui a condição que determina se a hora deverá ser atualizada e acumulada. Por exemplo, o tempo não deve ser considerado se exceder o período atividade, se o status do sistema estiver Inativo ou se o incidente tiver um status pendente.

Embora a situação detalhada aqui normalmente usa a função Tools.NetTime() para calcular o tempo, poderá haver casos em que é preferível usar a função VB padrão DateDiff().

A função Tools.NetTime provoca uma sobrecarga de verificação do período de atividade cada vez que é usada. É recomendável evitar o uso de NetTime nos procedimentos do evento de dados, pois eles são chamados para qualquer novo evento de entrada e, portanto, invoca a chamada NetTime. Se o período de atividade for 24/7, recomenda-se que você use a função DateDiff para evitar a sobrecarga de verificação do período de atividade.

Exemplo 1:

A rotina dos contadores de atualização a seguir acumula o período de tempo total na variável PeriodNetTime. Em AvailabilityTime, a rotina acumula a hora em que o status do sistema estava Ativo, significando que o sistema estava disponível.

O objeto Tools contém o método NetTime, NetTime(beginTime, endTime)0. Este método retorna o número de segundos entre beginTime e endTime que estiverem dentro do período de atividade da métrica atual. Qualquer hora entre essas duas variáveis é parte do período de atividade excluído, por isso, é muito usada para os cálculos de duração em que um período de atividade é usado. (Por exemplo: para tickets com prioridade 1 resolvidos em até quatro horas do horário comercial, mesmo que o ticket tenha sido gerado no fim de um dia útil, e não puder ser solucionado até a próxima manhã, ele ainda estará dentro do SLA, devido às horas do período de atividade a ser excluído).

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

Exemplo 2:

O exemplo a seguir calcula a disponibilidade de aplicativos tratando de eventos ativos e inativos de vários componentes essenciais, bem como eventos de manutenção desses componentes. Se todos os componentes estiverem em manutenção, o tempo não é considerado como tempo de disponibilidade esperado.

A subrotina UpdateCounters avança os contadores de tempo quando necessário e é executada com cada evento recebido para a fórmula (evento de dados brutos/ evento do mecanismo). Ele também atualiza a hora disponível esperada nos casos em que a hora estiver dentro do período de atividade e os componentes não estiverem dentro de um período de inatividade planejado. A fórmula atualiza o tempo de disponibilidade real somente quando também tiver o status do sistema como Ativo.

O DateDiff é uma função VB padrão que retorna a hora entre duas datas, mas não exclui nenhuma informação do período de atividade.

'Forçar a declaração da variável
Option Explicit

Variáveis globais
Dim ExpectedAvailabilityTime
Dim ActualAvailabilityTime
Dim LastUpdateTime
Dim AvailabilityIndicators
Dim MonitoredComponents
Dim DowntimeStatuses

'Mapear criação de objetos
Set AvailabilityIndicators=CreateObject("SlalomMap.Map")
Set MonitoredComponents=CreateObject("SlalomMap.Map")
Set DowntimeStatuses=CreateObject("SlalomMap.Map")

Após o carregamento e sempre que ocorrer uma alteração na infraestrutura
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")

   Certifique-se de que a fórmula está monitorando apenas e todos os recursos relevantes
   UpdateMonitoredComponents AllocatedComponents
End Sub

Sub OnLoad(time)
   Quando o sistema for ativado pela primeira vez, supõe-se que a disponibilidade está OK
   LastUpdateTime = time
End Sub

Sub OnPeriodStart(time)
   inicializar contadores para renovar cálculos periódicos
   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
   'gravar status de disponibilidade do recurso relatado
   AvailabilityIndicators(eventDetails.ResourceId) = _
      AvailabilityIndicators(eventDetails.ResourceId)+1
End Sub

Sub OnComponentUpEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'gravar status de disponibilidade do recurso relatado
   AvailabilityIndicators(eventDetails.ResourceId)= _
      AvailabilityIndicators(eventDetails.ResourceId)-1
End Sub

Sub OnMaintenanceStartEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'gravar status de disponibilidade do recurso relatado
   DowntimeStatuses(eventDetails.ResourceId)= _
      DowntimeStatuses(eventDetails.ResourceId)+1
End Sub

Sub OnMaintenanceEndEvent(eventDetails)
   UpdateCounters eventDetails.Time
   'gravar status de disponibilidade do recurso relatado
   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
      atualizar contadores de segundos no período (quando a disponibilidade é esperada)
      ExpectedAvailabilityTime = ExpectedAvailabilityTime + DateDiff("s",LastUpdateTime,time)
      If SystemIsAvailable Then
         'update seconds-of-availability counter
         ActualAvailabilityTime = ActualAvailabilityTime + DateDiff("s",LastUpdateTime,time)
      End If
   End If
   LastUpdateTime=time
End Sub

Sub UpdateMonitoredComponents(allocatedComponents)
   Componente Dim
   'adicionar ao mapa de componentes monitorados todos os novos componentes a serem monitorados
   Para cada componente no allocatedComponents
      If Not MonitoredComponents.Exist(Component) Then
         MonitoredComponents(Component) = Component
         AvailabilityIndicators(Component) = 0
         DowntimeStatuses(Component) = 0
      End If
   Próximo

   'remova do mapa de componentes monitorados todos os componentes que não são mais relevantes
   Para cada componente no MonitoredComponents
      If Not allocatedComponents.Exist(Component) Then
         MonitoredComponents.Erase Component
         AvailabilityIndicators.Erase Component
         DowntimeStatuses.Erase Component
      End If
   Próximo
End Sub

Function SystemIsAvailable
   Dim SystemAvailability
   SystemAvailability = True

   Componente Dim
   Dim ComponentAvailability
   Para cada componente no MonitoredComponents
      ComponentAvailability = AvailabilityIndicators(Component) = 0 _
         Or DowntimeStatuses(Component) > 0
      ' a disponibilidade do sistema é avaliada com disponibilidade
      SystemAvailability = SystemAvailability And ComponentAvailability
   Próximo
   SystemIsAvailable = SystemAvailability
End Function

Function AllComponentsAreInPlannedDowntime
   Dim ComponentsInPlannedDowntime
   ComponentsInPlannedDowntime = 0
   Componente Dim
   Para cada componente no MonitoredComponents
      If DowntimeStatuses(Component) > 0 Then
         ComponentsInPlannedDowntime = ComponentsInPlannedDowntime + 1
      End If
   Próximo

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