refactor: improve panel sync performance

This commit is contained in:
3252a8
2026-05-20 23:18:03 +03:00
parent a7f298743d
commit 5001185bf8
11 changed files with 230 additions and 28 deletions
+53
View File
@@ -1,8 +1,10 @@
from datetime import datetime, timedelta, timezone
from types import SimpleNamespace
from bot.handlers.admin.sync_admin import (
_coerce_panel_telegram_id,
_description_matches,
_should_update_lifetime_used_traffic,
_subscription_update_delta,
)
from db.models import Subscription
@@ -69,3 +71,54 @@ def test_subscription_update_delta_returns_only_changed_fields():
"is_active": False,
"status_from_panel": "EXPIRED",
}
def test_lifetime_traffic_update_waits_for_time_window_for_small_delta():
now = datetime(2026, 5, 20, 12, 0, tzinfo=timezone.utc)
settings = SimpleNamespace(
PANEL_SYNC_LIFETIME_TRAFFIC_MIN_INTERVAL_SECONDS=3600,
PANEL_SYNC_LIFETIME_TRAFFIC_MIN_DELTA_BYTES=100 * 1024 * 1024,
)
user = SimpleNamespace(
lifetime_used_traffic_bytes=10 * 1024 * 1024,
lifetime_used_traffic_synced_at=now - timedelta(minutes=15),
)
assert not _should_update_lifetime_used_traffic(
user,
11 * 1024 * 1024,
now=now,
settings=settings,
)
assert _should_update_lifetime_used_traffic(
user,
11 * 1024 * 1024,
now=now + timedelta(hours=1),
settings=settings,
)
def test_lifetime_traffic_update_allows_large_delta_and_skips_duplicate_panel_identity():
now = datetime(2026, 5, 20, 12, 0, tzinfo=timezone.utc)
settings = SimpleNamespace(
PANEL_SYNC_LIFETIME_TRAFFIC_MIN_INTERVAL_SECONDS=3600,
PANEL_SYNC_LIFETIME_TRAFFIC_MIN_DELTA_BYTES=100 * 1024 * 1024,
)
user = SimpleNamespace(
lifetime_used_traffic_bytes=10 * 1024 * 1024,
lifetime_used_traffic_synced_at=now,
)
assert _should_update_lifetime_used_traffic(
user,
200 * 1024 * 1024,
now=now,
settings=settings,
)
assert not _should_update_lifetime_used_traffic(
user,
0,
now=now + timedelta(hours=2),
settings=settings,
is_duplicate_panel_identity=True,
)
+19
View File
@@ -106,6 +106,25 @@ class PanelApiServiceLoggingTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(get_calls, 2)
async def test_get_all_panel_users_falls_back_to_100_when_large_page_fails(self):
service = self._make_service()
requested_sizes = []
async def fake_request(method, endpoint, **kwargs):
params = kwargs.get("params") or {}
size = params.get("size")
requested_sizes.append(size)
if size == 1000:
return {"error": True, "status_code": 400}
return {"response": {"users": [{"uuid": "user-uuid"}]}}
service._request = AsyncMock(side_effect=fake_request)
users = await service.get_all_panel_users()
self.assertEqual(users, [{"uuid": "user-uuid"}])
self.assertEqual(requested_sizes, [1000, 100])
if __name__ == "__main__":
unittest.main()
+9 -1
View File
@@ -1,5 +1,5 @@
from db.migrator import MIGRATIONS
from db.models import SupportTicket, SupportTicketMessage
from db.models import SupportTicket, SupportTicketMessage, User
def test_support_migration_is_registered_after_existing_revisions():
@@ -11,6 +11,10 @@ def test_support_migration_is_registered_after_existing_revisions():
assert ids.index("0025_add_support_notification_timestamps") > ids.index(
"0024_add_support_tickets"
)
assert "0026_add_lifetime_traffic_synced_at" in ids
assert ids.index("0026_add_lifetime_traffic_synced_at") > ids.index(
"0025_add_support_notification_timestamps"
)
def test_support_models_expose_expected_tables():
@@ -21,3 +25,7 @@ def test_support_models_expose_expected_tables():
assert "ix_support_tickets_status_last_msg" in {
index.name for index in SupportTicket.__table__.indexes
}
def test_user_model_tracks_lifetime_traffic_sync_timestamp():
assert "lifetime_used_traffic_synced_at" in User.__table__.columns