github.com/status-im/status-go@v1.1.0/server/pairing/statecontrol/state_management.go (about) 1 package statecontrol 2 3 // TODO refactor into the pairing package once the backend dependencies have been removed. 4 5 import ( 6 "fmt" 7 "sync" 8 ) 9 10 var ( 11 ErrProcessStateManagerAlreadyPairing = fmt.Errorf("cannot start new LocalPairing session, already pairing") 12 ErrProcessStateManagerAlreadyPaired = func(sessionName string) error { 13 return fmt.Errorf("given connection string already successfully used '%s'", sessionName) 14 } 15 ) 16 17 // ProcessStateManager represents a g 18 type ProcessStateManager struct { 19 pairing bool 20 pairingLock sync.Mutex 21 22 // sessions represents a map[string]bool: 23 // where string is a ConnectionParams string and bool is the transfer success state of that connection string 24 sessions sync.Map 25 } 26 27 // IsPairing returns if the ProcessStateManager is currently in pairing mode 28 func (psm *ProcessStateManager) IsPairing() bool { 29 psm.pairingLock.Lock() 30 defer psm.pairingLock.Unlock() 31 return psm.pairing 32 } 33 34 // SetPairing sets the ProcessStateManager pairing state 35 func (psm *ProcessStateManager) SetPairing(state bool) { 36 psm.pairingLock.Lock() 37 defer psm.pairingLock.Unlock() 38 psm.pairing = state 39 } 40 41 // RegisterSession stores a sessionName with the default false value. 42 // In practice a sessionName will be a ConnectionParams string provided by the server mode device. 43 // The boolean value represents whether the ConnectionParams string session resulted in a successful transfer. 44 func (psm *ProcessStateManager) RegisterSession(sessionName string) { 45 psm.sessions.Store(sessionName, false) 46 } 47 48 // CompleteSession updates a transfer session with a given transfer success state only if the session is registered. 49 func (psm *ProcessStateManager) CompleteSession(sessionName string) { 50 r, c := psm.GetSession(sessionName) 51 if r && !c { 52 psm.sessions.Store(sessionName, true) 53 } 54 } 55 56 // GetSession returns two booleans for a given sessionName. 57 // These represent if the sessionName has been registered and if it has resulted in a successful transfer 58 func (psm *ProcessStateManager) GetSession(sessionName string) (bool, bool) { 59 completed, registered := psm.sessions.Load(sessionName) 60 if !registered { 61 return registered, false 62 } 63 return registered, completed.(bool) 64 } 65 66 // StartPairing along with StopPairing are the core functions of the ProcessStateManager 67 // This function takes a sessionName, which in practice is a ConnectionParams string, and attempts to init pairing state management. 68 // The function will return an error if the ProcessStateManager is already currently pairing or if the sessionName was previously successful. 69 func (psm *ProcessStateManager) StartPairing(sessionName string) error { 70 if psm.IsPairing() { 71 return ErrProcessStateManagerAlreadyPairing 72 } 73 74 registered, completed := psm.GetSession(sessionName) 75 if completed { 76 return ErrProcessStateManagerAlreadyPaired(sessionName) 77 } 78 if !registered { 79 psm.RegisterSession(sessionName) 80 } 81 82 psm.SetPairing(true) 83 return nil 84 } 85 86 // StopPairing takes a sessionName and an error, if the error is nil the sessionName will be recorded as successful 87 // the pairing state of the ProcessStateManager is set to false. 88 func (psm *ProcessStateManager) StopPairing(sessionName string, err error) { 89 if err == nil { 90 psm.CompleteSession(sessionName) 91 } 92 psm.SetPairing(false) 93 }