@@ -13,7 +13,6 @@ import (
1313 "regexp"
1414 "slices"
1515 "strings"
16- "sync"
1716 "text/template"
1817 "time"
1918
@@ -69,8 +68,6 @@ type CaptchaProtect struct {
6968 ipv6Mask net.IPMask
7069 protectRoutesRegex []* regexp.Regexp
7170 excludeRoutesRegex []* regexp.Regexp
72- lastStateMtime time.Time
73- stateMu sync.Mutex
7471}
7572
7673type CaptchaConfig struct {
@@ -577,26 +574,14 @@ func (bc *CaptchaProtect) trippedRateLimit(ip string) bool {
577574}
578575
579576func (bc * CaptchaProtect ) registerRequest (ip string ) {
580- // Check if subnet already exists in cache
581- _ , exists := bc .rateCache .Get (ip )
582- if ! exists {
583- // New subnet - check disk first in case another instance has seen it
584- if bc .config .PersistentStateFile != "" {
585- bc .reconcileStateFromDisk ()
586- }
587-
588- // Try to add again after reconciliation
589- _ , stillExists := bc .rateCache .Get (ip )
590- if ! stillExists {
591- bc .rateCache .Set (ip , uint (1 ), lru .DefaultExpiration )
592- return
593- }
577+ err := bc .rateCache .Add (ip , uint (1 ), lru .DefaultExpiration )
578+ if err == nil {
579+ return
594580 }
595581
596- // Subnet exists, increment it
597- _ , err := bc .rateCache .IncrementUint (ip , uint (1 ))
582+ _ , err = bc .rateCache .IncrementUint (ip , uint (1 ))
598583 if err != nil {
599- bc .log .Error ("unable to increment rate cache" , "ip" , ip , "err" , err )
584+ bc .log .Error ("unable to set rate cache" , "ip" , ip , "err" , err )
600585 }
601586}
602587
@@ -783,52 +768,6 @@ func (bc *CaptchaProtect) saveStateNow() {
783768 bc .log .Debug ("State saved successfully" )
784769}
785770
786- // reconcileStateFromDisk checks if the state file has been modified and reconciles if needed.
787- // Uses mtime checking to avoid unnecessary disk reads.
788- func (bc * CaptchaProtect ) reconcileStateFromDisk () {
789- bc .stateMu .Lock ()
790- defer bc .stateMu .Unlock ()
791-
792- // Check file modification time first - avoid unnecessary reads
793- info , err := os .Stat (bc .config .PersistentStateFile )
794- if err != nil {
795- // File doesn't exist yet or can't be read
796- return
797- }
798-
799- // Only read if file was modified since last check
800- if ! info .ModTime ().After (bc .lastStateMtime ) {
801- return
802- }
803-
804- bc .lastStateMtime = info .ModTime ()
805-
806- // File has been modified, read and reconcile
807- lock , err := state .NewFileLock (bc .config .PersistentStateFile + ".lock" )
808- if err != nil {
809- return // Silent fail
810- }
811- defer lock .Close ()
812-
813- if err := lock .Lock (); err != nil {
814- return // Another instance is writing
815- }
816-
817- fileContent , err := os .ReadFile (bc .config .PersistentStateFile )
818- if err != nil || len (fileContent ) == 0 {
819- return
820- }
821-
822- var fileState state.State
823- if err := json .Unmarshal (fileContent , & fileState ); err != nil {
824- return
825- }
826-
827- // Reconcile all caches with file state
828- state .ReconcileState (fileState , bc .rateCache , bc .botCache , bc .verifiedCache )
829- bc .log .Debug ("Reconciled state from disk" )
830- }
831-
832771func (bc * CaptchaProtect ) loadState () {
833772 lock , err := state .NewFileLock (bc .config .PersistentStateFile + ".lock" )
834773 if err != nil {
0 commit comments