GNServer 0.0.0.0.22__py3-none-any.whl → 0.0.0.0.23__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.
GNServer/_app.py CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
 
4
4
  import re
5
+ import sys
5
6
  import uuid
6
7
  import anyio
7
8
  import decimal
@@ -829,6 +830,11 @@ class App:
829
830
  wait: bool = True,
830
831
  run: Optional[Callable] = None
831
832
  ):
833
+ """
834
+ # Запустить сервер
835
+
836
+ Запускает сервер в главном процессе asyncio.run()
837
+ """
832
838
 
833
839
  self.domain = domain
834
840
 
@@ -863,3 +869,27 @@ class App:
863
869
  await asyncio.Event().wait()
864
870
 
865
871
  asyncio.run(_main())
872
+
873
+
874
+ def runByVMHost(self):
875
+ """
876
+ # Запусить через VM-host
877
+
878
+ Заупскает сервер через процесс vm-host
879
+ """
880
+ argv = sys.argv[1:]
881
+ command = argv[0]
882
+ if command == 'gn:vm-host:start':
883
+ domain = argv[1]
884
+ port = int(argv[2])
885
+ cert_path = argv[3]
886
+ key_path = argv[4]
887
+ host = argv[5]
888
+
889
+ self.run(
890
+ domain=domain,
891
+ port=port,
892
+ cert_path=cert_path,
893
+ key_path=key_path,
894
+ host=host
895
+ )
GNServer/tools/_models.py CHANGED
@@ -1,5 +1,8 @@
1
1
  import time
2
- import threading
2
+ import asyncio
3
+ from typing import Optional
4
+
5
+
3
6
 
4
7
  class TTLDict:
5
8
  def __init__(self, default_ttl: int = 60, cleanup_interval: int = 300):
@@ -7,46 +10,38 @@ class TTLDict:
7
10
  :param default_ttl: TTL по умолчанию (сек), если при записи не указан
8
11
  :param cleanup_interval: периодическая очистка от просроченных ключей (сек), по умолчанию 5 мин
9
12
  """
13
+
10
14
  self._store = {}
11
- self._lock = threading.Lock()
12
15
  self._default_ttl = default_ttl
13
16
  self._cleanup_interval = cleanup_interval
14
- self._stop_event = threading.Event()
15
-
16
- self._timer = threading.Thread(target=self._cleanup_worker, daemon=True)
17
- self._timer.start()
17
+ self._task = None
18
18
 
19
- def set(self, key, value, ttl: int = None):
20
- """Установить значение с временем жизни (в секундах)."""
19
+ def set(self, key, value, ttl: Optional[int] = None):
21
20
  if ttl is None:
22
21
  ttl = self._default_ttl
23
22
  expire_at = time.monotonic() + ttl
24
- with self._lock:
25
- self._store[key] = (value, expire_at)
23
+ self._store[key] = (value, expire_at)
24
+
25
+ if self._task is None:
26
+ loop = asyncio.get_running_loop()
27
+ self._task = loop.create_task(self._cleanup_worker())
26
28
 
27
29
  def get(self, key):
28
- """Получить значение или None, если ключ отсутствует/просрочен."""
29
30
  now = time.monotonic()
30
- with self._lock:
31
- item = self._store.get(key)
32
- if not item:
33
- return None
34
-
35
- value, expire_at = item
36
- if expire_at < now:
37
- del self._store[key]
38
- return None
31
+ item = self._store.get(key)
32
+ if not item:
33
+ return None
39
34
 
40
- return value
35
+ value, expire_at = item
36
+ if expire_at < now:
37
+ del self._store[key]
38
+ return None
39
+ return value
41
40
 
42
41
  def __setitem__(self, key, value):
43
- """
44
- cache[key] = val → TTL по умолчанию
45
- """
46
42
  self.set(key, value, self._default_ttl)
47
43
 
48
44
  def __getitem__(self, key):
49
- """cache[key] -> value | None"""
50
45
  return self.get(key)
51
46
 
52
47
  def __contains__(self, key):
@@ -58,20 +53,22 @@ class TTLDict:
58
53
  def __repr__(self):
59
54
  return f"<TTLDict size={len(self._store)}>"
60
55
 
61
- def _cleanup_worker(self):
62
- """Фоновый поток для периодической очистки."""
63
- while not self._stop_event.wait(self._cleanup_interval):
56
+ async def _cleanup_worker(self):
57
+ while True:
58
+ await asyncio.sleep(self._cleanup_interval)
64
59
  self.cleanup()
65
60
 
66
61
  def cleanup(self):
67
- """Удалить все просроченные ключи."""
62
+ """Удалить все просроченные ключи"""
68
63
  now = time.monotonic()
69
- with self._lock:
70
- expired = [k for k, (_, exp) in self._store.items() if exp < now]
71
- for k in expired:
72
- self._store.pop(k, None)
64
+ expired = [k for k, (_, exp) in self._store.items() if exp < now]
65
+ for k in expired:
66
+ self._store.pop(k, None)
73
67
 
74
- def stop(self):
68
+ async def stop(self):
75
69
  """Остановить фон очистки"""
76
- self._stop_event.set()
77
- self._timer.join(timeout=1)
70
+ self._task.cancel()
71
+ try:
72
+ await self._task
73
+ except asyncio.CancelledError:
74
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GNServer
3
- Version: 0.0.0.0.22
3
+ Version: 0.0.0.0.23
4
4
  Summary: GNServer
5
5
  Home-page: https://github.com/KeyisB/libs/tree/main/GNServer
6
6
  Author: KeyisB
@@ -0,0 +1,11 @@
1
+ GNServer/___client.py,sha256=hmeUL2Vqp-BnwJeRcLZAaIfRNVxBrRRB_AFk9ofkei4,25459
2
+ GNServer/__init__.py,sha256=V50sMYrrPdOGuI1iJm-SW7izhX-eggDH16AHvtIKjmM,1480
3
+ GNServer/_app.py,sha256=w7v3z-E4VEINzeYScdVFpOzGxhuZk6VB7PFg3n1mMQQ,30689
4
+ GNServer/_client.py,sha256=lwFGsNR2RullSNCuu7WXXdYfUbsV1_ZweMv-N-5Gpv0,27371
5
+ GNServer/tools/__init__.py,sha256=itqkS5iBB2GEHqz8H-htqgd55rUi6utnuKVAzBBByCM,28
6
+ GNServer/tools/_models.py,sha256=1V94cbNHQGAl5l9DJbGvvkm1gmsgTEMgkjzlnZk8ymw,2264
7
+ gnserver-0.0.0.0.23.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
8
+ gnserver-0.0.0.0.23.dist-info/METADATA,sha256=jqN0cSl1gDDgjSACXbfpsDKv--dh0v6JFQY531SegmE,805
9
+ gnserver-0.0.0.0.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
+ gnserver-0.0.0.0.23.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
11
+ gnserver-0.0.0.0.23.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- GNServer/___client.py,sha256=hmeUL2Vqp-BnwJeRcLZAaIfRNVxBrRRB_AFk9ofkei4,25459
2
- GNServer/__init__.py,sha256=V50sMYrrPdOGuI1iJm-SW7izhX-eggDH16AHvtIKjmM,1480
3
- GNServer/_app.py,sha256=Mtpuoj7CPjedW9m5wL6YzfAwCV9F-5a69ag2Dh2VwIk,29908
4
- GNServer/_client.py,sha256=lwFGsNR2RullSNCuu7WXXdYfUbsV1_ZweMv-N-5Gpv0,27371
5
- GNServer/tools/__init__.py,sha256=itqkS5iBB2GEHqz8H-htqgd55rUi6utnuKVAzBBByCM,28
6
- GNServer/tools/_models.py,sha256=tXWR255ASJLlpdDrgMXcmRqD_nIcCb4qKeESvAhxWpU,2742
7
- gnserver-0.0.0.0.22.dist-info/licenses/LICENSE,sha256=WH_t7dKZyWJ5Ld07eYIkUG4Tv6zZWXtAdsUqYAUesn0,1084
8
- gnserver-0.0.0.0.22.dist-info/METADATA,sha256=b0GuFIDOkuPhFhVj_Cm66zZsjpm1nvQLvzLjGZhZhFA,805
9
- gnserver-0.0.0.0.22.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- gnserver-0.0.0.0.22.dist-info/top_level.txt,sha256=-UOUBuD4u7Qkb1o5PdcwyA3kx8xCH2lwy0tJHi26Wb4,9
11
- gnserver-0.0.0.0.22.dist-info/RECORD,,