示例#1
0
    def __init__(self, provider: ViewChangerDataProvider, timer: TimerService):
        self.provider = provider
        self._timer = timer

        self.inBox = deque()
        self.outBox = deque()
        self.inBoxRouter = Router(
            (InstanceChange, self.process_instance_change_msg)
        )

        self.instance_changes = InstanceChangeProvider(self.config.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL,
                                                       node_status_db=self.provider.node_status_db)

        self.previous_view_no = None

        # Action for _schedule instanceChange messages
        self.instance_change_action = None

        # Count of instance change rounds
        self.instance_change_rounds = 0

        # Time for view_change_starting
        self.start_view_change_ts = 0

        # Force periodic view change if enabled in config
        force_view_change_freq = self.config.ForceViewChangeFreq
        if force_view_change_freq > 0:
            RepeatingTimer(self._timer, force_view_change_freq, self.on_master_degradation)

        # Start periodic freshness check
        state_freshness_update_interval = self.config.STATE_FRESHNESS_UPDATE_INTERVAL
        if state_freshness_update_interval > 0:
            RepeatingTimer(self._timer, state_freshness_update_interval, self.check_freshness)
示例#2
0
    def __init__(self, provider: ViewChangerDataProvider, timer: TimerService):
        self.provider = provider
        self._timer = timer
        self.pre_vc_strategy = None

        self._view_no = 0  # type: int

        self.inBox = deque()
        self.outBox = deque()
        self.inBoxRouter = Router(
            (InstanceChange, self.process_instance_change_msg),
            (ViewChangeDone, self.process_vchd_msg),
            (FutureViewChangeDone, self.process_future_view_vchd_msg))

        self.instance_changes = InstanceChangeProvider(
            self.config.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL,
            node_status_db=self.provider.node_status_db)

        # Tracks if other nodes are indicating that this node is in lower view
        # than others. Keeps a map of view no to senders
        # TODO: Consider if sufficient ViewChangeDone for 2 different (and
        # higher views) are received, should one view change be interrupted in
        # between.
        self._next_view_indications = {}

        self._view_change_in_progress = False
        self.pre_view_change_in_progress = False

        self.previous_view_no = None
        self.previous_master_primary = None

        self.set_defaults()

        self.initInsChngThrottling()

        # Action for _schedule instanceChange messages
        self.instance_change_action = None

        # Count of instance change rounds
        self.instance_change_rounds = 0

        # Time for view_change_starting
        self.start_view_change_ts = 0

        # Last successful viewNo.
        # In some cases view_change process can be uncompleted in time.
        # In that case we want to know, which viewNo was successful (last completed view_change)
        self.last_completed_view_no = 0

        # Force periodic view change if enabled in config
        force_view_change_freq = self.config.ForceViewChangeFreq
        if force_view_change_freq > 0:
            RepeatingTimer(self._timer, force_view_change_freq,
                           self.on_master_degradation)

        # Start periodic freshness check
        state_freshness_update_interval = self.config.STATE_FRESHNESS_UPDATE_INTERVAL
        if state_freshness_update_interval > 0:
            RepeatingTimer(self._timer, state_freshness_update_interval,
                           self.check_freshness)
示例#3
0
    def __init__(self,
                 data: ConsensusSharedData,
                 timer: TimerService,
                 bus: InternalBus,
                 network: ExternalBus,
                 db_manager: DatabaseManager,
                 stasher: StashingRouter,
                 is_master_degraded: Callable[[], bool],
                 metrics: MetricsCollector = NullMetricsCollector()):
        self._data = data
        self._timer = timer
        self._bus = bus
        self._network = network
        self._stasher = stasher
        self._is_master_degraded = is_master_degraded
        self.metrics = metrics

        self._config = getConfig()

        self._instance_changes = \
            InstanceChangeProvider(outdated_ic_interval=self._config.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL,
                                   node_status_db=db_manager.get_store(NODE_STATUS_DB_LABEL),
                                   time_provider=timer.get_current_time)

        self._subscription = Subscription()
        self._subscription.subscribe(bus, VoteForViewChange, self.process_vote_for_view_change)
        self._subscription.subscribe(bus, NewViewAccepted, self.process_new_view_accepted)
        self._subscription.subscribe(stasher, InstanceChange, self.process_instance_change)
示例#4
0
def test_fail_update_instance_changes_from_db(instance_change_provider, tconf,
                                              node_status_db, time_provider,
                                              logsearch):
    # test updating cache with view without votes
    node_status_db.iterator = lambda include_value=True: {
        "3": node_status_db_serializer.serialize(None)
    }.items()
    provider = InstanceChangeProvider(
        tconf.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL, node_status_db,
        time_provider)
    assert not provider.has_view(3)

    # test updating cache with Vote with incorrect timestamp format
    node_status_db.iterator = lambda include_value=True: {
        "3": node_status_db_serializer.serialize({"voter": ["a", 10.4]})
    }.items()
    logs, _ = logsearch(msgs=[
        "InstanceChangeProvider: timestamp in Vote .* : .* - .* must "
        "be of float or int type"
    ])
    InstanceChangeProvider(tconf.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL,
                           node_status_db, time_provider)
    assert logs

    # test updating cache with Vote with incorrect reason format
    node_status_db.iterator = lambda include_value=True: {
        "3": node_status_db_serializer.serialize({"voter": [5, 10.4]})
    }.items()
    logs, _ = logsearch(msgs=[
        "InstanceChangeProvider: reason in Vote .* : .* - .* must "
        "be of int type"
    ])
    InstanceChangeProvider(tconf.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL,
                           node_status_db, time_provider)
    assert logs

    # test updating cache with incorrect view_no format
    node_status_db.iterator = lambda include_value=True: {
        "a": node_status_db_serializer.serialize({"voter": [5, 25]})
    }.items()
    logs, _ = logsearch(
        msgs=["InstanceChangeProvider: view_no='.*' "
              "must be of int type"])
    InstanceChangeProvider(tconf.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL,
                           node_status_db, time_provider)
    assert logs
def test_update_instance_changes_in_db(instance_change_provider, tconf,
                                       node_status_db, time_provider):
    frm = "Node1"
    view_no = 1
    msg = InstanceChange(view_no, Suspicions.PRIMARY_DEGRADED.code)

    assert not instance_change_provider.has_view(view_no)
    assert not instance_change_provider.has_inst_chng_from(view_no, frm)
    assert not _is_view_in_db(view_no, instance_change_provider)

    instance_change_provider.add_vote(msg, frm)
    assert instance_change_provider.has_view(view_no)
    assert instance_change_provider.has_inst_chng_from(view_no, frm)
    assert _is_view_in_db(view_no, instance_change_provider)

    instance_change_provider._node_status_db.close()
    assert instance_change_provider._node_status_db.closed
    instance_change_provider._node_status_db.open()

    new_instance_change_provider = InstanceChangeProvider(
        tconf.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL, node_status_db,
        time_provider)
    assert new_instance_change_provider.has_view(view_no)
    assert new_instance_change_provider.has_inst_chng_from(view_no, frm)
def instance_change_provider(tconf, node_status_db, time_provider):
    return InstanceChangeProvider(
        tconf.OUTDATED_INSTANCE_CHANGES_CHECK_INTERVAL, node_status_db,
        time_provider)