jvserve 2.1.14__tar.gz → 2.1.16__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.
Potentially problematic release.
This version of jvserve might be problematic. Click here for more details.
- {jvserve-2.1.14 → jvserve-2.1.16}/PKG-INFO +1 -1
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/cli.py +2 -0
- jvserve-2.1.16/jvserve/lib/agent_pulse.py +63 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve.egg-info/PKG-INFO +1 -1
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve.egg-info/SOURCES.txt +1 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/LICENSE +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/README.md +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/__init__.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/lib/__init__.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/lib/agent_interface.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/lib/file_interface.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/lib/jac_interface.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve/lib/jvlogger.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve.egg-info/dependency_links.txt +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve.egg-info/entry_points.txt +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve.egg-info/requires.txt +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/jvserve.egg-info/top_level.txt +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/setup.cfg +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/setup.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/tests/test_file_interface.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/tests/test_jvlogger.py +0 -0
- {jvserve-2.1.14 → jvserve-2.1.16}/tests/test_jvserve.py +0 -0
|
@@ -33,6 +33,7 @@ from typing_extensions import Any
|
|
|
33
33
|
from watchfiles import Change, watch
|
|
34
34
|
|
|
35
35
|
from jvserve.lib.agent_interface import AgentInterface
|
|
36
|
+
from jvserve.lib.agent_pulse import AgentPulse
|
|
36
37
|
from jvserve.lib.file_interface import (
|
|
37
38
|
DEFAULT_FILES_ROOT,
|
|
38
39
|
FILE_INTERFACE,
|
|
@@ -220,6 +221,7 @@ def run_jivas(filename: str, host: str = "localhost", port: int = 8000) -> None:
|
|
|
220
221
|
|
|
221
222
|
async def on_shutdown() -> None:
|
|
222
223
|
jvlogger.info("JIVAS is shutting down...")
|
|
224
|
+
AgentPulse.stop()
|
|
223
225
|
|
|
224
226
|
app = JaseciFastAPI.get()
|
|
225
227
|
app_lifespan = app.router.lifespan_context
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Agent Pulse class for scheduling and running agent jobs."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import threading
|
|
5
|
+
import time
|
|
6
|
+
|
|
7
|
+
import schedule
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AgentPulse:
|
|
11
|
+
"""Agent Pulse class for scheduling and running agent jobs."""
|
|
12
|
+
|
|
13
|
+
EVENT = None
|
|
14
|
+
THREAD = None
|
|
15
|
+
LOGGER = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def start(interval: int = 1) -> threading.Event:
|
|
19
|
+
"""Starts the agent pulse in a separate thread that executes
|
|
20
|
+
pending jobs at each elapsed time interval.
|
|
21
|
+
|
|
22
|
+
This method ensures that only one thread is running at a time
|
|
23
|
+
to prevent duplication. If a thread is already running, it logs
|
|
24
|
+
a message and returns without starting a new thread.
|
|
25
|
+
|
|
26
|
+
@param interval: Time in seconds between each execution cycle of
|
|
27
|
+
scheduled jobs.
|
|
28
|
+
@return: threading.Event which can be set to stop the running
|
|
29
|
+
thread.
|
|
30
|
+
|
|
31
|
+
Note: It is intended behavior that run_continuously() does not
|
|
32
|
+
run missed jobs. For instance, a job scheduled to run every
|
|
33
|
+
minute with a run interval of one hour will only run once per
|
|
34
|
+
hour, not 60 times at once.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
if AgentPulse.THREAD and AgentPulse.THREAD.is_alive():
|
|
38
|
+
AgentPulse.LOGGER.info("agent pulse is already running.")
|
|
39
|
+
return AgentPulse.EVENT
|
|
40
|
+
|
|
41
|
+
AgentPulse.EVENT = threading.Event()
|
|
42
|
+
|
|
43
|
+
class ScheduleThread(threading.Thread):
|
|
44
|
+
def run(self) -> None:
|
|
45
|
+
while AgentPulse.EVENT and not AgentPulse.EVENT.is_set():
|
|
46
|
+
schedule.run_pending()
|
|
47
|
+
time.sleep(interval)
|
|
48
|
+
|
|
49
|
+
AgentPulse.THREAD = ScheduleThread()
|
|
50
|
+
AgentPulse.THREAD.start()
|
|
51
|
+
|
|
52
|
+
AgentPulse.LOGGER.info("agent pulse started.")
|
|
53
|
+
|
|
54
|
+
return AgentPulse.EVENT
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def stop() -> None:
|
|
58
|
+
"""Stops the agent pulse."""
|
|
59
|
+
if AgentPulse.EVENT and not AgentPulse.EVENT.is_set():
|
|
60
|
+
AgentPulse.LOGGER.info("agent pulse stopped.")
|
|
61
|
+
AgentPulse.EVENT.set()
|
|
62
|
+
if AgentPulse.THREAD:
|
|
63
|
+
AgentPulse.THREAD.join()
|
|
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
|