Feature: Automatically start frp client for subordinate #2
Reference in New Issue
Block a user
Delete Branch "feature/auto_frp"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
licenses.ini was hit on every heartbeat -- 5s x clients x ~8 SetStr per auth -- with no concurrency protection. Two consequences: 1. 100 concurrent online would saturate the file (~160 writes/sec, full-file rewrite each via WritePrivateProfileString). 2. Concurrent SetPendingRenewal / DecrementPendingQuota with no lock occasionally clobbered freshly-set renewal quotas (reported by user as "preset renewal silently disappears"). Add LicensesIniMutex() (Meyers singleton recursive_mutex, exposed in CPasswordDlg.h so both CPasswordDlg.cpp and CLicenseDlg.cpp share it) and wrap all 15 functions that touch licenses.ini. Rewrite UpdateLicenseActivity around g_activityCache (in-memory state keyed by "SN|IP|machine"): skip the entire write path when nothing changed and the 30s LastActiveTime throttle window hasn't expired. Passcode/HMAC are only flushed on actual change (renewal path); IP list is only rewritten when the yyMMdd timestamp would roll a day. Measured impact (local 2-client baseline): before: 0.60 writes/sec (4 writes per heartbeat cluster) after: 0.07 writes/sec (one write per client per 30s throttle) Extrapolated to the 100-online target: before: ~160 writes/sec (saturation) after: ~3.3 writes/sec (100 clients / 30s throttle window) Race elimination is the more important win: PendingQuota's read-modify-write is now atomic, so the "preset renewal disappears" race is closed. Notes from audit (these landed during the same iteration): - Cache key is (SN, IP, machine), not SN alone. A single SN can be shared by 100+ end machines in bulk-license deployments, so a per-SN cache flips on every heartbeat and defeats suppression. Per-(SN, IP, machine) throttling is what makes the 100/30 model actually hold; an SN-only key reproduced the original ~0.7 writes/s. - DeleteLicense invalidates the per-SN activity cache via InvalidateLicenseActivityCache() (prefix scan since one SN maps to many cache entries). Without this, cache hits after delete would skip the auto-recreate path and leave the section permanently missing. - OnLicenseViewIPs: m_ListLicense.SetItemText moved outside the lock so the critical section only covers disk I/O.