diff --git a/patroni/global_config.py b/patroni/global_config.py index 7731cf59f..ded66f6fe 100644 --- a/patroni/global_config.py +++ b/patroni/global_config.py @@ -44,19 +44,20 @@ def _cluster_has_valid_config(cluster: Optional['Cluster']) -> bool: """ return bool(cluster and cluster.config and cluster.config.modify_version) - def update(self, cluster: Optional['Cluster']) -> None: + def update(self, cluster: Optional['Cluster'], default: Optional[Dict[str, Any]] = None) -> None: """Update with the new global configuration from the :class:`Cluster` object view. .. note:: - Global configuration is updated only when configuration in the *cluster* view is valid. - Update happens in-place and is executed only from the main heartbeat thread. :param cluster: the currently known cluster state from DCS. + :param default: default configuration, which will be used if there is no valid *cluster.config*. """ # Try to protect from the case when DCS was wiped out if self._cluster_has_valid_config(cluster): self.__config = cluster.config.data # pyright: ignore [reportOptionalMemberAccess] + elif default: + self.__config = default def from_cluster(self, cluster: Optional['Cluster']) -> 'GlobalConfig': """Return :class:`GlobalConfig` instance from the provided :class:`Cluster` object view. diff --git a/patroni/ha.py b/patroni/ha.py index 16c050f37..59b5b6dd1 100644 --- a/patroni/ha.py +++ b/patroni/ha.py @@ -185,6 +185,9 @@ def __init__(self, patroni: Patroni): # used only in backoff after failing a pre_promote script self._released_leader_key_timestamp = 0 + # Initialize global config + global_config.update(None, self.patroni.config.dynamic_configuration) + def primary_stop_timeout(self) -> Union[int, None]: """:returns: "primary_stop_timeout" from the global configuration or `None` when not in synchronous mode.""" ret = global_config.primary_stop_timeout diff --git a/tests/test_ha.py b/tests/test_ha.py index 43844c5d9..abfb4691b 100644 --- a/tests/test_ha.py +++ b/tests/test_ha.py @@ -256,8 +256,6 @@ def test_bootstrap_as_standby_leader(self, initialize): self.p.data_directory_empty = true self.ha.cluster = get_cluster_not_initialized_without_leader( cluster_config=ClusterConfig(1, {"standby_cluster": {"port": 5432}}, 1)) - global_config.update(self.ha.cluster) - self.ha.cluster = get_cluster_not_initialized_without_leader(cluster_config=ClusterConfig(0, {}, 0)) self.assertEqual(self.ha.run_cycle(), 'trying to bootstrap a new standby leader') def test_bootstrap_waiting_for_standby_leader(self): @@ -323,7 +321,6 @@ def test_crash_recovery(self): self.ha.state_handler.cancellable._process = Mock() self.ha._crash_recovery_started -= 600 self.ha.cluster.config.data.update({'maximum_lag_on_failover': 10}) - global_config.update(self.ha.cluster) self.assertEqual(self.ha.run_cycle(), 'terminated crash recovery because of startup timeout') @patch.object(Rewind, 'ensure_clean_shutdown', Mock()) @@ -776,7 +773,6 @@ def test_manual_switchover_from_leader(self): with patch('patroni.ha.logger.info') as mock_info: self.ha.fetch_node_status = get_node_status(wal_position=1) self.ha.cluster.config.data.update({'maximum_lag_on_failover': 5}) - global_config.update(self.ha.cluster) self.assertEqual(self.ha.run_cycle(), 'no action. I am (postgresql0), the leader with the lock') self.assertEqual(mock_info.call_args_list[0][0], ('Member %s exceeds maximum replication lag', 'leader')) @@ -1282,7 +1278,6 @@ def test_failover_immediately_on_zero_primary_start_timeout(self, demote): self.p.is_running = false self.ha.cluster = get_cluster_initialized_with_leader(sync=(self.p.name, 'other')) self.ha.cluster.config.data.update({'synchronous_mode': True, 'primary_start_timeout': 0}) - global_config.update(self.ha.cluster) self.ha.has_lock = true self.ha.update_lock = true self.ha.fetch_node_status = get_node_status() # accessible, in_recovery @@ -1391,7 +1386,6 @@ def test_process_sync_replication(self): mock_set_sync.reset_mock() self.p.sync_handler.current_state = Mock(return_value=(CaseInsensitiveSet(), CaseInsensitiveSet())) self.ha.cluster.config.data['synchronous_mode_strict'] = True - global_config.update(self.ha.cluster) self.ha.run_cycle() mock_set_sync.assert_called_once_with(CaseInsensitiveSet('*'))