update_state

in source/plugins/ruby/health/health_monitor_state.rb [62:222]


        def update_state(monitor, 
            monitor_config, 
            is_aggregate_monitor = false,
            telemetry = nil
        )
            samples_to_keep = 1
            monitor_id = monitor.monitor_id
            monitor_instance_id = monitor.monitor_instance_id
            log = HealthMonitorHelpers.get_log_handle
            current_time = Time.now.utc.iso8601
            health_monitor_instance_state = get_state(monitor_instance_id)
            if !health_monitor_instance_state.nil?
                health_monitor_instance_state.is_state_change_consistent = false
                health_monitor_instance_state.should_send = false
                set_state(monitor_instance_id, health_monitor_instance_state) 
            end

            if !monitor_config.nil? && !monitor_config['ConsecutiveSamplesForStateTransition'].nil?
                samples_to_keep = monitor_config['ConsecutiveSamplesForStateTransition'].to_i
            end

            deleted_record = {}
            if @@monitor_states.key?(monitor_instance_id)
                health_monitor_instance_state = @@monitor_states[monitor_instance_id]
                health_monitor_records = health_monitor_instance_state.prev_records 

                if health_monitor_records.size == samples_to_keep
                    deleted_record = health_monitor_records.delete_at(0)
                end
                health_monitor_records.push(monitor.details)
                health_monitor_instance_state.prev_records = health_monitor_records
                @@monitor_states[monitor_instance_id] = health_monitor_instance_state
            else
                

                old_state = HealthMonitorStates::NONE
                new_state = HealthMonitorStates::NONE
                if samples_to_keep == 1
                    new_state = monitor.state
                end

                health_monitor_instance_state = HealthMonitorInstanceState.new(
                    monitor.transition_date_time,
                    old_state,
                    new_state,
                    monitor.transition_date_time,
                    [monitor.details])

                health_monitor_instance_state.should_send = true
                @@monitor_states[monitor_instance_id] = health_monitor_instance_state
            end

            
            

            health_monitor_records = health_monitor_instance_state.prev_records
            if monitor_config['ConsecutiveSamplesForStateTransition'].nil?
                samples_to_check = 1
            else
                samples_to_check = monitor_config['ConsecutiveSamplesForStateTransition'].to_i
            end

            latest_record = health_monitor_records[health_monitor_records.size-1] 
            latest_record_state = latest_record["state"]
            latest_record_time = latest_record["timestamp"] 

            new_state = health_monitor_instance_state.new_state
            prev_sent_time = health_monitor_instance_state.prev_sent_record_time

            
            if latest_record_state.downcase == new_state.downcase
                time_elapsed = (Time.parse(latest_record_time) - Time.parse(prev_sent_time)) / 60
                
                if time_elapsed > @@health_signal_timeout 
                    
                    health_monitor_instance_state.old_state = health_monitor_instance_state.new_state
                    health_monitor_instance_state.new_state = latest_record_state
                    health_monitor_instance_state.prev_sent_record_time = current_time
                    health_monitor_instance_state.should_send = true
                    
                    set_state(monitor_instance_id, health_monitor_instance_state)
                    log.debug "#{monitor_instance_id} condition: signal timeout should_send #{health_monitor_instance_state.should_send} #{health_monitor_instance_state.old_state} --> #{health_monitor_instance_state.new_state}"
                
                elsif !@@first_record_sent.key?(monitor_instance_id)
                    @@first_record_sent[monitor_instance_id] = true
                    health_monitor_instance_state.should_send = true
                    set_state(monitor_instance_id, health_monitor_instance_state)
                elsif agg_monitor_details_changed?(is_aggregate_monitor, deleted_record, health_monitor_instance_state.prev_records[0])
                    health_monitor_instance_state.should_send = true
                    set_state(monitor_instance_id, health_monitor_instance_state)
                    log.debug "#{monitor_instance_id} condition: agg monitor details changed should_send #{health_monitor_instance_state.should_send}"
                end
            
            else
                
                if latest_record_state.downcase == HealthMonitorStates::NONE
                    health_monitor_instance_state.old_state = health_monitor_instance_state.new_state 
                    health_monitor_instance_state.new_state = latest_record_state
                    health_monitor_instance_state.state_change_time = current_time
                    health_monitor_instance_state.prev_sent_record_time = current_time
                    health_monitor_instance_state.should_send = true
                    if !is_aggregate_monitor
                        if !telemetry.nil?
                            telemetry.add_monitor_to_telemetry(monitor_id, health_monitor_instance_state.old_state, health_monitor_instance_state.new_state)
                        end
                    end
                    if !@@first_record_sent.key?(monitor_instance_id)
                        @@first_record_sent[monitor_instance_id] = true
                    end
                    set_state(monitor_instance_id, health_monitor_instance_state)
                    log.debug "#{monitor_instance_id} condition: NONE state should_send #{health_monitor_instance_state.should_send} #{health_monitor_instance_state.old_state} --> #{health_monitor_instance_state.new_state}"
                
                
                elsif samples_to_check == 1
                    health_monitor_instance_state.old_state = health_monitor_instance_state.new_state 
                    health_monitor_instance_state.new_state = latest_record_state
                    health_monitor_instance_state.state_change_time = current_time
                    health_monitor_instance_state.prev_sent_record_time = current_time
                    health_monitor_instance_state.should_send = true
                    if !is_aggregate_monitor
                        if !telemetry.nil?
                            telemetry.add_monitor_to_telemetry(monitor_id, health_monitor_instance_state.old_state, health_monitor_instance_state.new_state)
                        end
                    end
                    if !@@first_record_sent.key?(monitor_instance_id)
                        @@first_record_sent[monitor_instance_id] = true
                    end
                    set_state(monitor_instance_id, health_monitor_instance_state)
                    log.debug "#{monitor_instance_id} condition: state change, samples_to_check = #{samples_to_check} should_send #{health_monitor_instance_state.should_send} #{health_monitor_instance_state.old_state} --> #{health_monitor_instance_state.new_state}"
                else
                    
                    
                    if (is_state_change_consistent(health_monitor_records, samples_to_keep))
                        first_record = health_monitor_records[0]
                        latest_record = health_monitor_records[health_monitor_records.size-1] 
                        latest_record_state = latest_record["state"]
                        latest_record_time = latest_record["timestamp"] 

                        health_monitor_instance_state.old_state = health_monitor_instance_state.new_state
                        health_monitor_instance_state.is_state_change_consistent = true 
                        health_monitor_instance_state.should_send = true
                        health_monitor_instance_state.new_state = latest_record_state
                        health_monitor_instance_state.prev_sent_record_time = current_time
                        health_monitor_instance_state.state_change_time = current_time
                        if !is_aggregate_monitor
                            if !telemetry.nil?
                                telemetry.add_monitor_to_telemetry(monitor_id, health_monitor_instance_state.old_state, health_monitor_instance_state.new_state)
                            end
                        end

                        set_state(monitor_instance_id, health_monitor_instance_state)

                        if !@@first_record_sent.key?(monitor_instance_id)
                            @@first_record_sent[monitor_instance_id] = true
                        end
                        log.debug "#{monitor_instance_id} condition: consistent state change, samples_to_check = #{samples_to_check} should_send #{health_monitor_instance_state.should_send} #{health_monitor_instance_state.old_state} --> #{health_monitor_instance_state.new_state}"
                    end
                end
            end
        end