CliRemote 1.8.0__py3-none-any.whl → 1.8.3__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.
- {cliremote-1.8.0.dist-info → cliremote-1.8.3.dist-info}/METADATA +1 -1
- {cliremote-1.8.0.dist-info → cliremote-1.8.3.dist-info}/RECORD +6 -6
- remote/precise_engine.py +13 -96
- {cliremote-1.8.0.dist-info → cliremote-1.8.3.dist-info}/WHEEL +0 -0
- {cliremote-1.8.0.dist-info → cliremote-1.8.3.dist-info}/licenses/LICENSE +0 -0
- {cliremote-1.8.0.dist-info → cliremote-1.8.3.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
cliremote-1.8.
|
1
|
+
cliremote-1.8.3.dist-info/licenses/LICENSE,sha256=O-0zMbcEi6wXz1DiSdVgzMlQjJcNqNe5KDv08uYzqR0,1055
|
2
2
|
remote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
remote/account_manager.py,sha256=TepnGIoE2hU-j_NmU5ByoS-JrboE0w3A1bYmQoQX5h8,15176
|
4
4
|
remote/account_viewer.py,sha256=j46KSjbgrBmBi7UxFeJ5tCwHIe0QvCvphkirGIbB2oo,5192
|
@@ -22,7 +22,7 @@ remote/joiner.py,sha256=CXTQ-l6CysqZSkYP1GUV1LM1qlh5wD4jBj_og_FVW1I,7773
|
|
22
22
|
remote/leave_controller.py,sha256=TIShgxCMiKyBn9ZdQZYm6Kf89GgDaoPCRH7pxqq9FC8,1167
|
23
23
|
remote/lefter.py,sha256=jxZmkl3NIe1c-WeVES8WBX21hW-eocfxfePvxddHdi0,6090
|
24
24
|
remote/mention_manager.py,sha256=I75ezmVZM0lYrgk8OQ2p-VETLLwM5FiW83tiBgbQ1CY,3257
|
25
|
-
remote/precise_engine.py,sha256=
|
25
|
+
remote/precise_engine.py,sha256=3LhyDcITIfscCgYTwWyJ-CTAWylrufqHeURR1FAwKvA,641
|
26
26
|
remote/profile_info.py,sha256=Us5mz6sdV_5-5wRx6F3S6rtj2m6vaP_HOrCBLgHXpD4,1992
|
27
27
|
remote/profile_media.py,sha256=lD_uIb0U3jeH_dpa4SNbF0wr1DQiQ5OfbTCOubcm9Us,2264
|
28
28
|
remote/profile_privacy.py,sha256=LrRZbbqhaYdl4JzBMJrl-D-N8y1AG2LR1DDzv-tmlV0,2298
|
@@ -33,7 +33,7 @@ remote/text_manager.py,sha256=C2wNSXPSCDu8NSD3RsfbKmUQMWOYd1B5N4tzy-Jsriw,2195
|
|
33
33
|
remote/username_manager.py,sha256=nMNdke-2FIv86xR1Y6rR-43oUoQu_3Khw8wEo54noXI,3388
|
34
34
|
remote/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
35
|
remote/utils/sqlite_utils.py,sha256=5i0oUXsBgKC_8qHZPJ-Gyhp9D1TwqKHVvuZRIhKpS6w,1260
|
36
|
-
cliremote-1.8.
|
37
|
-
cliremote-1.8.
|
38
|
-
cliremote-1.8.
|
39
|
-
cliremote-1.8.
|
36
|
+
cliremote-1.8.3.dist-info/METADATA,sha256=OsHKIAwSjhPU2NGE8vUv8FuKc9xNe4tUwTadfrJk_z4,1202
|
37
|
+
cliremote-1.8.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
38
|
+
cliremote-1.8.3.dist-info/top_level.txt,sha256=yBZidJ6zCix_a2ubGlYaewvlzBFXWbckQt20dudxJ1E,7
|
39
|
+
cliremote-1.8.3.dist-info/RECORD,,
|
remote/precise_engine.py
CHANGED
@@ -1,102 +1,19 @@
|
|
1
1
|
# antispam_core/precise_engine.py
|
2
|
-
import asyncio
|
3
|
-
import time
|
4
|
-
from dataclasses import dataclass
|
2
|
+
import asyncio, time
|
5
3
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
last_jitter_ns: int = 0 # wakeup - target (>= 0)
|
11
|
-
|
12
|
-
class HiPrecisionTicker:
|
13
|
-
"""
|
14
|
-
Drift-free asyncio ticker with hybrid coarse-sleep + fine spin.
|
15
|
-
- Absolute scheduling: next_target = prev_target + period (no cumulative drift).
|
16
|
-
- Coarse sleep via asyncio, then busy-wait for final microseconds.
|
17
|
-
- Uses time.perf_counter_ns() (monotonic, high-resolution).
|
18
|
-
|
19
|
-
Notes:
|
20
|
-
* Sub-microsecond accuracy is NOT realistic on general OS with Python.
|
21
|
-
* 'spin' burns CPU on the running core; keep margins reasonable.
|
22
|
-
* Tune margins for your hardware/OS.
|
23
|
-
|
24
|
-
Args:
|
25
|
-
interval_sec: desired period in seconds (float).
|
26
|
-
sleep_margin_ns: if remaining > (sleep_margin + spin_margin), we await asyncio.sleep.
|
27
|
-
spin_margin_ns: final window to busy-wait (e.g., 50-200 µs).
|
28
|
-
|
29
|
-
Stats:
|
30
|
-
.stats.last_jitter_ns gives (actual_wakeup - scheduled_target) in ns.
|
31
|
-
"""
|
32
|
-
|
33
|
-
__slots__ = (
|
34
|
-
"period_ns", "sleep_margin_ns", "spin_margin_ns",
|
35
|
-
"next_target_ns", "stats"
|
36
|
-
)
|
37
|
-
|
38
|
-
def __init__(self,
|
39
|
-
interval_sec: float,
|
40
|
-
sleep_margin_ns: int = 200_000, # 200 µs
|
41
|
-
spin_margin_ns: int = 50_000): # 50 µs
|
42
|
-
if interval_sec <= 0:
|
43
|
-
raise ValueError("interval_sec must be > 0")
|
44
|
-
self.period_ns = int(interval_sec * 1e9)
|
45
|
-
if self.period_ns <= 1_000: # sanity: <1 µs period is nonsense for Python
|
46
|
-
raise ValueError("interval too small for Python environment")
|
47
|
-
if sleep_margin_ns < 0 or spin_margin_ns < 0:
|
48
|
-
raise ValueError("margins must be non-negative")
|
49
|
-
self.sleep_margin_ns = int(sleep_margin_ns)
|
50
|
-
self.spin_margin_ns = int(spin_margin_ns)
|
51
|
-
self.next_target_ns: int | None = None
|
52
|
-
self.stats = TickerStats()
|
4
|
+
class PreciseTicker:
|
5
|
+
def __init__(self, interval: float):
|
6
|
+
self.interval = float(interval)
|
7
|
+
self.next_tick = time.perf_counter()
|
53
8
|
|
54
9
|
async def sleep(self):
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
if
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if remaining <= 0:
|
64
|
-
# We're already late: skip sleeping, jump target forward
|
65
|
-
# so we don't try to "catch up" with negative sleeps.
|
66
|
-
self.stats.last_target_ns = self.next_target_ns
|
67
|
-
self.stats.last_wakeup_ns = now
|
68
|
-
self.stats.last_jitter_ns = now - self.next_target_ns
|
69
|
-
self.next_target_ns = now + self.period_ns
|
70
|
-
return
|
71
|
-
|
72
|
-
# Coarse sleep: leave 'spin_margin_ns' to finish in busy-wait.
|
73
|
-
# Also keep a 'sleep_margin_ns' cushion to reduce overshoot risk.
|
74
|
-
coarse_threshold = self.sleep_margin_ns + self.spin_margin_ns
|
75
|
-
if remaining > coarse_threshold:
|
76
|
-
# target - spin_margin => leave that much for spinning
|
77
|
-
coarse_sleep_ns = remaining - self.spin_margin_ns
|
78
|
-
# asyncio.sleep takes seconds
|
79
|
-
await asyncio.sleep(coarse_sleep_ns / 1e9)
|
80
|
-
|
81
|
-
# Fine spin until target
|
82
|
-
target = self.next_target_ns
|
83
|
-
while True:
|
84
|
-
now = time.perf_counter_ns()
|
85
|
-
if now >= target:
|
86
|
-
break
|
87
|
-
# Tight spin: do nothing. If you see high CPU, you can insert
|
88
|
-
# a minimal pause on some platforms via time.sleep(0) sporadically,
|
89
|
-
# but that will hurt accuracy.
|
90
|
-
|
91
|
-
# Record stats
|
92
|
-
self.stats.last_target_ns = target
|
93
|
-
self.stats.last_wakeup_ns = now
|
94
|
-
self.stats.last_jitter_ns = now - target # >= 0
|
95
|
-
|
96
|
-
# Advance absolute target by exactly one period (no drift accumulation)
|
97
|
-
self.next_target_ns = target + self.period_ns
|
10
|
+
"""خواب دقیق بدون drift در زمان"""
|
11
|
+
self.next_tick += self.interval
|
12
|
+
delay = self.next_tick - time.perf_counter()
|
13
|
+
if delay > 0:
|
14
|
+
await asyncio.sleep(delay)
|
15
|
+
else:
|
16
|
+
self.next_tick = time.perf_counter() # ریست در صورت عقب افتادن
|
98
17
|
|
99
18
|
def reset(self):
|
100
|
-
|
101
|
-
self.next_target_ns = None
|
102
|
-
self.stats = TickerStats()
|
19
|
+
self.next_tick = time.perf_counter()
|
File without changes
|
File without changes
|
File without changes
|