github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/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  }