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 +30 -0
- GNServer/tools/_models.py +33 -36
- {gnserver-0.0.0.0.22.dist-info → gnserver-0.0.0.0.23.dist-info}/METADATA +1 -1
- gnserver-0.0.0.0.23.dist-info/RECORD +11 -0
- gnserver-0.0.0.0.22.dist-info/RECORD +0 -11
- {gnserver-0.0.0.0.22.dist-info → gnserver-0.0.0.0.23.dist-info}/WHEEL +0 -0
- {gnserver-0.0.0.0.22.dist-info → gnserver-0.0.0.0.23.dist-info}/licenses/LICENSE +0 -0
- {gnserver-0.0.0.0.22.dist-info → gnserver-0.0.0.0.23.dist-info}/top_level.txt +0 -0
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
|
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.
|
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
|
-
|
25
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
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.
|
77
|
-
|
70
|
+
self._task.cancel()
|
71
|
+
try:
|
72
|
+
await self._task
|
73
|
+
except asyncio.CancelledError:
|
74
|
+
pass
|
@@ -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,,
|
File without changes
|
File without changes
|
File without changes
|