serverish 2.0.1__tar.gz → 2.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {serverish-2.0.1 → serverish-2.0.3}/PKG-INFO +1 -1
- {serverish-2.0.1 → serverish-2.0.3}/pyproject.toml +1 -1
- {serverish-2.0.1 → serverish-2.0.3}/serverish/connection/connection.py +6 -2
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_reader.py +24 -5
- {serverish-2.0.1 → serverish-2.0.3}/LICENSE +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/README.md +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/__init__.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/__init__.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/asyncio_util_functions.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/collector.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/datetime.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/exceptions.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/fifoset.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/hasstatuses.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/idmanger.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/iterators.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/manageable.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/singleton.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/status.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/base/task_manager.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/connection/__init__.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/connection/connection_jets.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/connection/connection_nats.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/__init__.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/live_document.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/logging.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/messenger.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_callback_sub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_cmd_pub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_cmd_sub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_core_pub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_core_read.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_core_sub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_document_read.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_journal_pub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_journal_read.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_progress_pub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_progress_read.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_publisher.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_rpc_req.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_rpc_resp.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_single_pub.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msg_single_read.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/messenger/msgvalidator.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/monitoring/__init__.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/monitoring/bridge.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/monitoring/factory.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/monitoring/monitored.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/monitoring/monitored_nats.py +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/config.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/default.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/include/timestamp.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/journal.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/meta.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/program_current_state.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/program_state.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/progress.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/schema/telemetry.schema.json +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/services/TODO.txt +0 -0
- {serverish-2.0.1 → serverish-2.0.3}/serverish/slog.py +0 -0
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
import asyncio
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
+
import shutil
|
|
5
6
|
import socket
|
|
6
7
|
from typing import Iterable
|
|
7
8
|
|
|
@@ -108,14 +109,17 @@ class Connection(HasStatuses):
|
|
|
108
109
|
Returns:
|
|
109
110
|
Status: Status object, named 'ping'
|
|
110
111
|
"""
|
|
112
|
+
ping_exec = shutil.which('ping')
|
|
113
|
+
if ping_exec is None:
|
|
114
|
+
return StatusReport.unknown(msg="'ping' command not found in PATH, skipping ping check")
|
|
111
115
|
|
|
112
116
|
async def _ping_host(host):
|
|
113
117
|
proc = await asyncio.create_subprocess_exec(
|
|
114
|
-
|
|
118
|
+
ping_exec, '-c', '1', host,
|
|
115
119
|
stdout=asyncio.subprocess.PIPE,
|
|
116
120
|
stderr=asyncio.subprocess.PIPE)
|
|
117
121
|
_stdout, _stderr = await proc.communicate()
|
|
118
|
-
return
|
|
122
|
+
return host, proc.returncode
|
|
119
123
|
|
|
120
124
|
if len(self.host) == 0:
|
|
121
125
|
return StatusReport.unknown(msg='No hosts to ping')
|
|
@@ -292,10 +292,13 @@ class MsgReader(MsgDriver):
|
|
|
292
292
|
log.debug(self.fmt(f"No messages available, finishing due to nowait"))
|
|
293
293
|
raise self.EndIterationException('nowait')
|
|
294
294
|
|
|
295
|
-
# Non-nowait mode: wait for NEW messages to arrive
|
|
296
|
-
# Break into shorter intervals
|
|
297
|
-
|
|
298
|
-
|
|
295
|
+
# Non-nowait mode: wait for NEW messages to arrive.
|
|
296
|
+
# Break into shorter intervals so the reconnect-needed
|
|
297
|
+
# check at the top of the loop runs often enough that
|
|
298
|
+
# low-rate subjects don't sit on a stale subscription
|
|
299
|
+
# for tens of seconds after a NATS reconnect.
|
|
300
|
+
blocking_interval = 2.0
|
|
301
|
+
max_wait_cycles = 50 # Total wait: 50 * 2s = 100s (unchanged)
|
|
299
302
|
|
|
300
303
|
for cycle in range(max_wait_cycles):
|
|
301
304
|
# Check for reconnection before each wait cycle
|
|
@@ -621,12 +624,28 @@ class MsgReader(MsgDriver):
|
|
|
621
624
|
max_retries = 3
|
|
622
625
|
for attempt in range(max_retries):
|
|
623
626
|
try:
|
|
624
|
-
# Clean up existing subscription
|
|
627
|
+
# Clean up existing subscription. `unsubscribe()` only detaches the
|
|
628
|
+
# local handle; the JetStream consumer must be deleted explicitly
|
|
629
|
+
# or it leaks server-side across every reconnect (one orphan per
|
|
630
|
+
# reopen, accumulating until the stream's consumer cap or the
|
|
631
|
+
# process restarts).
|
|
625
632
|
if self.pull_subscription is not None:
|
|
633
|
+
try:
|
|
634
|
+
ci = await self.pull_subscription.consumer_info()
|
|
635
|
+
except Exception as e:
|
|
636
|
+
log.debug(f"Error fetching consumer_info during reopen attempt {attempt + 1}: {e}")
|
|
637
|
+
ci = None
|
|
626
638
|
try:
|
|
627
639
|
await self.pull_subscription.unsubscribe()
|
|
628
640
|
except Exception as e:
|
|
629
641
|
log.debug(f"Error unsubscribing during reopen attempt {attempt + 1}: {e}")
|
|
642
|
+
if ci is not None:
|
|
643
|
+
try:
|
|
644
|
+
await self.connection.js.delete_consumer(stream=ci.stream_name, consumer=ci.name)
|
|
645
|
+
except nats.js.errors.NotFoundError:
|
|
646
|
+
pass # already gone, nothing to delete
|
|
647
|
+
except Exception as e:
|
|
648
|
+
log.debug(f"Error deleting old consumer during reopen attempt {attempt + 1}: {e}")
|
|
630
649
|
|
|
631
650
|
# Create new consumer configuration
|
|
632
651
|
consumer_conf = await self._create_consumer_cfg()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|