github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/connection_status.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package libkbfs 6 7 import ( 8 "sync" 9 ) 10 11 // Service names used in ConnectionStatus. 12 const ( 13 KeybaseServiceName = "keybase-service" 14 MDServiceName = "md-server" 15 GregorServiceName = "gregor" 16 LoginStatusUpdateName = "login" 17 LogoutStatusUpdateName = "logout" 18 ) 19 20 type errDisconnected struct{} 21 22 func (errDisconnected) Error() string { return "Disconnected" } 23 24 type kbfsCurrentStatus struct { 25 lock sync.Mutex 26 failingServices map[string]error 27 invalidateChan chan StatusUpdate 28 } 29 30 // Init inits the kbfsCurrentStatus. 31 func (kcs *kbfsCurrentStatus) Init() { 32 kcs.failingServices = map[string]error{} 33 kcs.invalidateChan = make(chan StatusUpdate) 34 } 35 36 // CurrentStatus returns a copy of the current status. 37 func (kcs *kbfsCurrentStatus) CurrentStatus() (map[string]error, chan StatusUpdate) { 38 kcs.lock.Lock() 39 defer kcs.lock.Unlock() 40 41 res := map[string]error{} 42 for k, v := range kcs.failingServices { 43 res[k] = v 44 } 45 return res, kcs.invalidateChan 46 } 47 48 // PushConnectionStatusChange pushes a change to the connection status of one of the services. 49 func (kcs *kbfsCurrentStatus) PushConnectionStatusChange(service string, err error) { 50 kcs.lock.Lock() 51 defer kcs.lock.Unlock() 52 53 if err != nil { 54 // Exit early if the service is already failed, to avoid an 55 // invalidation. 56 _, errExisted := kcs.failingServices[service] 57 kcs.failingServices[service] = err 58 if errExisted { 59 return 60 } 61 } else { 62 // Potentially exit early if nothing changes. 63 _, exist := kcs.failingServices[service] 64 if !exist { 65 return 66 } 67 delete(kcs.failingServices, service) 68 } 69 70 close(kcs.invalidateChan) 71 kcs.invalidateChan = make(chan StatusUpdate) 72 } 73 74 // PushStatusChange forces a new status be fetched by status listeners. 75 func (kcs *kbfsCurrentStatus) PushStatusChange() { 76 kcs.lock.Lock() 77 defer kcs.lock.Unlock() 78 close(kcs.invalidateChan) 79 kcs.invalidateChan = make(chan StatusUpdate) 80 }