refactor: improve panel sync performance
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user