jvserve 2.1.18__py3-none-any.whl → 2.1.20__py3-none-any.whl
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.
Potentially problematic release.
This version of jvserve might be problematic. Click here for more details.
- jvserve/cli.py +71 -0
- {jvserve-2.1.18.dist-info → jvserve-2.1.20.dist-info}/METADATA +1 -1
- {jvserve-2.1.18.dist-info → jvserve-2.1.20.dist-info}/RECORD +7 -7
- {jvserve-2.1.18.dist-info → jvserve-2.1.20.dist-info}/WHEEL +0 -0
- {jvserve-2.1.18.dist-info → jvserve-2.1.20.dist-info}/entry_points.txt +0 -0
- {jvserve-2.1.18.dist-info → jvserve-2.1.20.dist-info}/licenses/LICENSE +0 -0
- {jvserve-2.1.18.dist-info → jvserve-2.1.20.dist-info}/top_level.txt +0 -0
jvserve/cli.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Module for registering CLI plugins for jaseci."""
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import json
|
|
4
5
|
import logging
|
|
5
6
|
import mimetypes
|
|
6
7
|
import os
|
|
@@ -9,6 +10,7 @@ import threading
|
|
|
9
10
|
import time
|
|
10
11
|
from concurrent.futures import ThreadPoolExecutor
|
|
11
12
|
from contextlib import asynccontextmanager
|
|
13
|
+
from datetime import datetime
|
|
12
14
|
from pickle import load
|
|
13
15
|
from typing import AsyncIterator, Optional
|
|
14
16
|
|
|
@@ -22,6 +24,7 @@ from fastapi import FastAPI, HTTPException, Request, Response
|
|
|
22
24
|
from fastapi.middleware.cors import CORSMiddleware
|
|
23
25
|
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
|
|
24
26
|
from jac_cloud.core.context import JaseciContext
|
|
27
|
+
from jac_cloud.jaseci.datasources.redis import Redis
|
|
25
28
|
from jac_cloud.jaseci.main import FastAPI as JaseciFastAPI # type: ignore
|
|
26
29
|
from jac_cloud.jaseci.utils import logger
|
|
27
30
|
from jac_cloud.jaseci.utils.logger import Level
|
|
@@ -41,6 +44,8 @@ from jvserve.lib.file_interface import (
|
|
|
41
44
|
)
|
|
42
45
|
from jvserve.lib.jvlogger import JVLogger
|
|
43
46
|
|
|
47
|
+
redis = Redis().get_rd()
|
|
48
|
+
|
|
44
49
|
load_dotenv(".env")
|
|
45
50
|
# quiet the jac_cloud logger down to errors only
|
|
46
51
|
logger.setLevel(Level.ERROR.value)
|
|
@@ -56,6 +61,10 @@ collection_init_lock = asyncio.Lock()
|
|
|
56
61
|
watcher_enabled = True
|
|
57
62
|
|
|
58
63
|
|
|
64
|
+
# taken from kubernetes HOSTNAME for replicated deployment
|
|
65
|
+
SERVER_ID = os.environ.get("HOSTNAME", "unknown_server")
|
|
66
|
+
|
|
67
|
+
|
|
59
68
|
async def get_url_proxy_collection() -> pymongo.collection.Collection:
|
|
60
69
|
"""Thread-safe initialization of MongoDB collection"""
|
|
61
70
|
global url_proxy_collection
|
|
@@ -335,6 +344,8 @@ def run_jivas(filename: str, host: str = "localhost", port: int = 8000) -> None:
|
|
|
335
344
|
jvlogger.info("Development mode: Starting file watcher")
|
|
336
345
|
start_file_watcher(watchdir, filename, host, port)
|
|
337
346
|
|
|
347
|
+
threading.Thread(target=redis_listener, daemon=True).start()
|
|
348
|
+
|
|
338
349
|
# Run the app
|
|
339
350
|
JaseciFastAPI.start(host=host, port=port)
|
|
340
351
|
|
|
@@ -422,3 +433,63 @@ class JacCmd:
|
|
|
422
433
|
def jvserve(filename: str, host: str = "localhost", port: int = 8000) -> None:
|
|
423
434
|
"""Launch unified JIVAS server with file services"""
|
|
424
435
|
run_jivas(filename, host, port)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def handle_message(msg: str) -> None:
|
|
439
|
+
"""
|
|
440
|
+
Handles incoming messages from the Redis channel 'jivas_actions'.
|
|
441
|
+
Expects the message to be a JSON string with 'action' and 'initiator' fields.
|
|
442
|
+
Only acts on 'reload_jivas' messages not sent by this pod.
|
|
443
|
+
"""
|
|
444
|
+
try:
|
|
445
|
+
data = json.loads(msg)
|
|
446
|
+
except json.JSONDecodeError:
|
|
447
|
+
print(f"Received invalid message: {msg}")
|
|
448
|
+
return
|
|
449
|
+
|
|
450
|
+
action = data.get("action")
|
|
451
|
+
initiator = data.get("initiator")
|
|
452
|
+
|
|
453
|
+
# Ignore messages sent by this pod
|
|
454
|
+
if initiator == SERVER_ID:
|
|
455
|
+
jvlogger.info("Skipping message from self")
|
|
456
|
+
return
|
|
457
|
+
|
|
458
|
+
if action == "reload_jivas":
|
|
459
|
+
print(f"Received reload_jivas action from {initiator}, executing reload.")
|
|
460
|
+
reload_jivas()
|
|
461
|
+
else:
|
|
462
|
+
print(f"Ignored action: {action} from {initiator}")
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def redis_listener() -> None:
|
|
466
|
+
"""Listens to the Redis channel 'walker_install_action' and handles incoming messages."""
|
|
467
|
+
pubsub = redis.pubsub()
|
|
468
|
+
pubsub.subscribe("jivas_actions")
|
|
469
|
+
jvlogger.info("Subscribed to channel: jivas_actions")
|
|
470
|
+
|
|
471
|
+
for message in pubsub.listen():
|
|
472
|
+
if message["type"] == "message":
|
|
473
|
+
handle_message(message["data"])
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def send_action_notification(action: str, extra_data: dict | None = None) -> None:
|
|
477
|
+
"""
|
|
478
|
+
Sends a message to the Redis channel 'jivas_actions'.
|
|
479
|
+
|
|
480
|
+
Args:
|
|
481
|
+
action (str): the action name, e.g., 'reload_jivas'
|
|
482
|
+
extra_data (dict): optional additional data to include in the message
|
|
483
|
+
"""
|
|
484
|
+
payload = {
|
|
485
|
+
"action": action,
|
|
486
|
+
"timestamp": datetime.utcnow().isoformat(),
|
|
487
|
+
"initiator": SERVER_ID,
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
if extra_data:
|
|
491
|
+
payload.update(extra_data)
|
|
492
|
+
|
|
493
|
+
# Publish the message
|
|
494
|
+
redis.publish("jivas_actions", json.dumps(payload))
|
|
495
|
+
jvlogger.info(f"Sent message: {payload}")
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
jvserve/__init__.py,sha256=Jd0pamSDn2wGTZkNk8I9qNYTFBHp7rasdYO0_Dvad_k,245
|
|
2
|
-
jvserve/cli.py,sha256=
|
|
2
|
+
jvserve/cli.py,sha256=CA1fg-pmn30gwl9V48KJ_ThuDOPfaCxZOGfAtOd4gCg,17058
|
|
3
3
|
jvserve/lib/__init__.py,sha256=cnzfSHLoTWG9Ygut2nOpDys5aPlQz-m0BSkB-nd7OMs,31
|
|
4
4
|
jvserve/lib/agent_interface.py,sha256=cO2ZgII33YU6m2zU_qTThAPoHcfg8V3dAMPFGaZAun4,5511
|
|
5
5
|
jvserve/lib/agent_pulse.py,sha256=6hBF6KQYr6Z9Mi_yoWKGfdnW7gg84kK20Slu-bLR_m8,2067
|
|
6
6
|
jvserve/lib/file_interface.py,sha256=VO9RBCtJwaBxu5eZjc57-uRbsVXXZt86wVRVq9R3KXY,6079
|
|
7
7
|
jvserve/lib/jac_interface.py,sha256=hugcHF6by6_fIFfmvW7fgRMVpKe471oEWEZEA53MtEQ,8148
|
|
8
8
|
jvserve/lib/jvlogger.py,sha256=RNiB9PHuBzTvNIQWhxoDgrDlNYA0PYm1SVpvzlqu8mE,4180
|
|
9
|
-
jvserve-2.1.
|
|
10
|
-
jvserve-2.1.
|
|
11
|
-
jvserve-2.1.
|
|
12
|
-
jvserve-2.1.
|
|
13
|
-
jvserve-2.1.
|
|
14
|
-
jvserve-2.1.
|
|
9
|
+
jvserve-2.1.20.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
10
|
+
jvserve-2.1.20.dist-info/METADATA,sha256=AfWbskfQRc0-i80MpBD5W_Mc-pSg-68KKq8W2q964ZE,4821
|
|
11
|
+
jvserve-2.1.20.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
jvserve-2.1.20.dist-info/entry_points.txt,sha256=HYyg1QXoLs0JRb004L300VeLOZyDLY27ynD1tnTnEN4,35
|
|
13
|
+
jvserve-2.1.20.dist-info/top_level.txt,sha256=afoCXZv-zXNBuhVIvfJGjafXKEiJl_ooy4BtgQwAG4Q,8
|
|
14
|
+
jvserve-2.1.20.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|