|
7 | 7 | import logging
|
8 | 8 | import os
|
9 | 9 | import pwd
|
| 10 | +from time import sleep |
10 | 11 | from typing import Any, TypedDict
|
11 | 12 |
|
12 | 13 | import requests
|
@@ -366,18 +367,32 @@ def is_replication_healthy(self) -> bool:
|
366 | 367 |
|
367 | 368 | def is_restart_pending(self) -> bool:
|
368 | 369 | """Returns whether the Patroni/PostgreSQL restart pending."""
|
369 |
| - patroni_status = requests.get( |
| 370 | + pending_restart = self._get_patroni_restart_pending() |
| 371 | + if pending_restart: |
| 372 | + # The current Patroni 3.2.2 has wired behaviour: it temporarily flags pending_restart=True |
| 373 | + # on any changes to REST API, which is gone within a second but long enough to be |
| 374 | + # caught by charm. Sleep 2 seconds as a protection here until Patroni 3.3.0 upgrade. |
| 375 | + # Repeat the request to make sure pending_restart flag is still here |
| 376 | + logger.debug("Enduring restart is pending (to avoid unnecessary rolling restarts)") |
| 377 | + sleep(2) |
| 378 | + pending_restart = self._get_patroni_restart_pending() |
| 379 | + |
| 380 | + return pending_restart |
| 381 | + |
| 382 | + def _get_patroni_restart_pending(self) -> bool: |
| 383 | + """Returns whether the Patroni flag pending_restart on REST API.""" |
| 384 | + r = requests.get( |
370 | 385 | f"{self._patroni_url}/patroni",
|
371 | 386 | verify=self._verify,
|
372 | 387 | timeout=PATRONI_TIMEOUT,
|
373 | 388 | auth=self._patroni_auth,
|
374 | 389 | )
|
375 |
| - try: |
376 |
| - pending_restart = patroni_status.json()["pending_restart"] |
377 |
| - except KeyError: |
378 |
| - pending_restart = False |
379 |
| - pass |
380 |
| - logger.debug(f"Patroni API is_restart_pending: {pending_restart}") |
| 390 | + pending_restart = r.json().get("pending_restart", False) |
| 391 | + logger.debug( |
| 392 | + f"API _get_patroni_restart_pending ({pending_restart}): %s (%s)", |
| 393 | + r, |
| 394 | + r.elapsed.total_seconds(), |
| 395 | + ) |
381 | 396 |
|
382 | 397 | return pending_restart
|
383 | 398 |
|
@@ -509,7 +524,7 @@ def ensure_slots_controller_by_patroni(self, slots: dict[str, str]) -> None:
|
509 | 524 | auth=self._patroni_auth,
|
510 | 525 | )
|
511 | 526 | slots_patch: dict[str, dict[str, str] | None] = dict.fromkeys(
|
512 |
| - current_config.json().get("slots", ()) |
| 527 | + current_config.json().get("slots") or {} |
513 | 528 | )
|
514 | 529 | for slot, database in slots.items():
|
515 | 530 | slots_patch[slot] = {
|
@@ -617,6 +632,8 @@ def render_patroni_yml_file(
|
617 | 632 | user_databases_map: map of databases to be accessible by each user.
|
618 | 633 | slots: replication slots (keys) with assigned database name (values).
|
619 | 634 | """
|
| 635 | + slots = slots or {} |
| 636 | + |
620 | 637 | # Open the template patroni.yml file.
|
621 | 638 | with open("templates/patroni.yml.j2") as file:
|
622 | 639 | template = Template(file.read())
|
|
0 commit comments