1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-03-31 20:25:34 -04:00

feat: Add configurable stale_timeout for APRS-IS connections

Add a new 'stale_timeout' configuration option to the aprs_network config
group that allows users to customize how long to wait before considering
an APRS-IS connection stale.

Problem:
The stale connection threshold was hardcoded to 2 minutes. In environments
with frequent network hiccups or when using certain APRS-IS servers that
may drop connections silently, 2 minutes can be too long to wait before
reconnecting, resulting in significant data loss.

Solution:
- Add 'stale_timeout' option to aprsd/conf/client.py with default of 120s
- Update APRSISDriver.__init__ to use the config value
- Maintain backward compatibility by defaulting to 120s if not configured
- Update tests to handle the new configuration option

Usage:
  [aprs_network]
  stale_timeout = 60  # Reconnect after 60 seconds without data

The default remains 120 seconds (2 minutes) for backward compatibility.
This commit is contained in:
Walter Boring 2026-03-27 10:05:44 -04:00
parent a2e07a2279
commit 930339d4cf
3 changed files with 28 additions and 3 deletions

View File

@ -32,8 +32,12 @@ class APRSISDriver:
connected = False
def __init__(self):
max_timeout = {'hours': 0.0, 'minutes': 2, 'seconds': 0}
self.max_delta = datetime.timedelta(**max_timeout)
# Use configurable stale_timeout, defaulting to 120 seconds if not set
try:
stale_timeout = CONF.aprs_network.stale_timeout
except (cfg.NoSuchOptError, cfg.NoSuchGroupError):
stale_timeout = 120 # Default to 2 minutes for backward compatibility
self.max_delta = datetime.timedelta(seconds=stale_timeout)
self.login_status = {
'success': False,
'message': None,

View File

@ -47,6 +47,14 @@ aprs_opts = [
default=14580,
help='APRS-IS port',
),
cfg.IntOpt(
'stale_timeout',
default=120,
help='Seconds without receiving data before connection is considered stale. '
'When a connection goes stale, it will be automatically reconnected. '
'Lower values detect dead connections faster but may cause unnecessary '
'reconnects during brief network hiccups. Default is 120 seconds (2 minutes).',
),
]
kiss_serial_opts = [

View File

@ -24,6 +24,7 @@ class TestAPRSISDriver(unittest.TestCase):
self.mock_conf.aprs_network.password = '12345'
self.mock_conf.aprs_network.host = 'rotate.aprs.net'
self.mock_conf.aprs_network.port = 14580
self.mock_conf.aprs_network.stale_timeout = 120 # Default 2 minutes
# Mock APRS Lib Client
self.aprslib_patcher = mock.patch('aprsd.client.drivers.aprsis.APRSLibClient')
@ -71,11 +72,23 @@ class TestAPRSISDriver(unittest.TestCase):
def test_init(self):
"""Test initialization sets default values."""
self.assertIsInstance(self.driver.max_delta, datetime.timedelta)
self.assertEqual(self.driver.max_delta, datetime.timedelta(minutes=2))
# Default stale_timeout is 120 seconds (2 minutes)
self.assertEqual(self.driver.max_delta, datetime.timedelta(seconds=120))
self.assertFalse(self.driver.login_status['success'])
self.assertIsNone(self.driver.login_status['message'])
self.assertIsNone(self.driver._client)
def test_init_custom_stale_timeout(self):
"""Test initialization with custom stale_timeout."""
# Set a custom stale_timeout
self.mock_conf.aprs_network.stale_timeout = 60 # 1 minute
# Create a new driver instance with custom timeout
driver = APRSISDriver.__new__(APRSISDriver)
driver.__init__()
self.assertEqual(driver.max_delta, datetime.timedelta(seconds=60))
def test_is_enabled_true(self):
"""Test is_enabled returns True when APRS-IS is enabled."""
self.mock_conf.aprs_network.enabled = True