github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/service/reachability.go (about)

     1  // Copyright 2015 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package service
     5  
     6  import (
     7  	"sync"
     8  
     9  	"golang.org/x/net/context"
    10  
    11  	"github.com/keybase/client/go/libkb"
    12  	"github.com/keybase/client/go/protocol/keybase1"
    13  	"github.com/keybase/go-framed-msgpack-rpc/rpc"
    14  )
    15  
    16  type reachabilityHandler struct {
    17  	*BaseHandler
    18  	libkb.Contextified
    19  	reachability *reachability
    20  }
    21  
    22  func newReachabilityHandler(xp rpc.Transporter, g *libkb.GlobalContext, reachability *reachability) *reachabilityHandler {
    23  	return &reachabilityHandler{
    24  		BaseHandler:  NewBaseHandler(g, xp),
    25  		Contextified: libkb.NewContextified(g),
    26  		reachability: reachability,
    27  	}
    28  }
    29  
    30  func (h *reachabilityHandler) ReachabilityChanged(_ context.Context, _ keybase1.Reachability) (err error) {
    31  	h.G().Trace("ReachabilityChanged", &err)()
    32  	return nil
    33  }
    34  
    35  func (h *reachabilityHandler) StartReachability(_ context.Context) (res keybase1.Reachability, err error) {
    36  	h.G().Trace("StartReachability", &err)()
    37  	return keybase1.Reachability{
    38  		Reachable: keybase1.Reachable_UNKNOWN,
    39  	}, nil
    40  }
    41  
    42  func (h *reachabilityHandler) CheckReachability(_ context.Context) (res keybase1.Reachability, err error) {
    43  	h.G().Trace("CheckReachability", &err)()
    44  	return h.reachability.check(), nil
    45  }
    46  
    47  type reachability struct {
    48  	libkb.Contextified
    49  	lastReachability keybase1.Reachability
    50  	setMutex         sync.Mutex
    51  
    52  	gh *gregorHandler
    53  }
    54  
    55  func newReachability(g *libkb.GlobalContext, gh *gregorHandler) *reachability {
    56  	return &reachability{
    57  		Contextified: libkb.NewContextified(g),
    58  		gh:           gh,
    59  	}
    60  }
    61  
    62  func (h *reachability) setReachability(r keybase1.Reachability) {
    63  	h.setMutex.Lock()
    64  	changed := h.lastReachability.Reachable != r.Reachable
    65  	h.lastReachability = r
    66  	h.setMutex.Unlock()
    67  
    68  	if changed {
    69  		h.G().Log.Debug("Reachability changed: %#v", r)
    70  		h.G().NotifyRouter.HandleReachability(r)
    71  	}
    72  }
    73  
    74  func (h *reachability) check() (k keybase1.Reachability) {
    75  	reachable := h.gh.isReachable()
    76  	if reachable {
    77  		k.Reachable = keybase1.Reachable_YES
    78  	} else {
    79  		k.Reachable = keybase1.Reachable_NO
    80  	}
    81  	h.setReachability(k)
    82  	return k
    83  }
    84  
    85  func (h *reachability) IsConnected(ctx context.Context) libkb.ConnectivityMonitorResult {
    86  	h.setMutex.Lock()
    87  	defer h.setMutex.Unlock()
    88  
    89  	switch h.lastReachability.Reachable {
    90  	case keybase1.Reachable_YES:
    91  		return libkb.ConnectivityMonitorYes
    92  	case keybase1.Reachable_NO:
    93  		return libkb.ConnectivityMonitorNo
    94  	default:
    95  		return libkb.ConnectivityMonitorUnknown
    96  	}
    97  }
    98  
    99  func (h *reachability) CheckReachability(ctx context.Context) error {
   100  	h.check()
   101  	return nil
   102  }