Gramps and adapting to intermittent Internet connectivity

I’ve been working on tweaking the Addon Manager and am a bit distressed about how long and fast it bangs retries when a target file/server is unavailable. I have found hundreds of 404 warning messages in my console when the internet is disconnected or it fails to find an addons-xx.json for the current locality.

(It was also concerning to see 404 warnings apparently from polling of the Project addons-en.json files during startup of Gramps. Since the Addon Manager’s Settings are set to “Never” for checking for updates, I did not expect to see Gramps polling project URLs unless the Addon Manager or Plugin Manager was active. )

With the addition of the FamilySearch active portal, what is the chance that Gramps will become unresponsive if a user has intermittent connectivity. Will it continuously retry until hitting some hard limit and then pop an warning dialog?

In future, if some feature starts pinging gramps-project.org, I am concerned that we may inadvertently create our own DoS attack.

So, are there guidelines for how to reduce unnecessary load when Gramps is trying to find a net resource? Some Signal/Callback for when there is a change in connectivity?

Perplexity sketched out a suggestion

When to use NetworkManager

If you want more detailed state than “available/not available,” NetworkManager’s D-Bus or libnm API is the stronger option. NetworkManager explicitly provides a D-Bus interface, and its libnm bindings are described as often simpler for GLib-based applications.stackoverflow

Gramps integration idea

For a Gramps add-on, the cleanest design is usually:

  • listen for Gio.NetworkMonitor::network-changed.
  • when available becomes true, emit your own internal callback or refresh event.
  • keep the Gramps-side logic separate so the addon can refresh only the pieces that depend on online access.

That gives you the same general “signal/callback” model Gramps uses, just driven by GTK/GIO rather than by Gramps core.networkmanager

Caveat

network-changed means the network configuration changed, not necessarily that a specific internet host is reachable. If your addon depends on a particular website or API, pair the signal with a quick reachability check using can_reach() or a lightweight probe before refreshing.
A usual requirement would be to debounce the connectivity signal so you only emit your Gramps refresh event after the network has stayed “available” for a short stable period. Gio.NetworkMonitor::network-changed fires on configuration changes, and GLib’s timeout helpers are suitable for delaying action, though they are not precise timers.docs.gtk+1

Debounce pattern

A common pattern is:

  • on every network-changed event, cancel any pending refresh timer.
  • start a new timeout for, say, 2–5 seconds.
  • when the timeout expires, check network_available again.
  • only then emit your internal “online restored” signal.

That way, brief flapping does not trigger repeated refreshes.

import gi
gi.require_version("Gio", "2.0")
gi.require_version("GLib", "2.0")
from gi.repository import Gio, GLib

class NetWatcher:
    def __init__(self, stable_ms=3000):
        self.monitor = Gio.NetworkMonitor.get_default()
        self.stable_ms = stable_ms
        self._timeout_id = 0
        self._last_available = self.monitor.get_network_available()
        self.monitor.connect("network-changed", self._on_network_changed)

    def _on_network_changed(self, monitor, available):
        self._last_available = available
        if self._timeout_id:
            GLib.source_remove(self._timeout_id)
            self._timeout_id = 0

        if available:
            self._timeout_id = GLib.timeout_add(self.stable_ms, self._emit_if_still_online)
        else:
            self._on_offline()

    def _emit_if_still_online(self):
        self._timeout_id = 0
        if self.monitor.get_network_available():
            self._on_online_stable()
        return False

    def _on_online_stable(self):
        pass

    def _on_offline(self):
        pass

Here’s an experimental replacement for the Addon Manager that is a bit more conservative in its net accessing. Unlike previous versions, it also includes all the tweaks from 5.2 to 6.1 branch.

It is a manual install. (Rename the old files and copy these files to folder supplant them.) Lightly tested with 5.2, 6.0 and 6.1 versions.

It has a new default for the addons filters: New or Updated

The Project validation will parse the raw.githubusercontent.com path or the path for any of the .json files.

gramps/gui/plug/_windows.py
_windows.py (144.7 KB)

/data/gramps.css
gramps.css (1.2 KB)

It would not be surprising to see a problem immediately after installing the replacement, restarting gramps and launching the Addon Manager. This seems to be related to the settings having more options and needing to be updated. See the posting: “Un-repeatable 1st-run crashes after Upgrading Gramps