github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libkbfs/shared_keybase_transport.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  	"github.com/keybase/backoff"
    11  	"github.com/keybase/client/go/libkb"
    12  	"github.com/keybase/client/go/logger"
    13  	"github.com/keybase/go-framed-msgpack-rpc/rpc"
    14  	"golang.org/x/net/context"
    15  )
    16  
    17  // NewSharedKeybaseConnection returns a connection that tries to
    18  // connect to the local keybase daemon.
    19  func NewSharedKeybaseConnection(kbCtx Context, config Config,
    20  	handler rpc.ConnectionHandler) *rpc.Connection {
    21  	transport := &SharedKeybaseTransport{kbCtx: kbCtx}
    22  	constBackoff := backoff.NewConstantBackOff(RPCReconnectInterval)
    23  	opts := rpc.ConnectionOpts{
    24  		WrapErrorFunc:    libkb.WrapError,
    25  		TagsFunc:         libkb.LogTagsFromContext,
    26  		ReconnectBackoff: func() backoff.BackOff { return constBackoff },
    27  	}
    28  	return rpc.NewConnectionWithTransport(
    29  		handler, transport, libkb.ErrorUnwrapper{},
    30  		logger.LogOutputWithDepthAdder{Logger: config.MakeLogger("")}, opts)
    31  }
    32  
    33  // SharedKeybaseTransport is a ConnectionTransport implementation that
    34  // uses a shared local socket to a keybase daemon.
    35  type SharedKeybaseTransport struct {
    36  	kbCtx Context
    37  
    38  	// Protects everything below.
    39  	mutex           sync.Mutex
    40  	transport       rpc.Transporter
    41  	stagedTransport rpc.Transporter
    42  }
    43  
    44  // Test that SharedKeybaseTransport fully implements the
    45  // ConnectionTransport interface.
    46  var _ rpc.ConnectionTransport = (*SharedKeybaseTransport)(nil)
    47  
    48  // Dial is an implementation of the ConnectionTransport interface.
    49  func (kt *SharedKeybaseTransport) Dial(ctx context.Context) (
    50  	rpc.Transporter, error) {
    51  	_, transport, _, err := kt.kbCtx.GetSocket(true)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	kt.mutex.Lock()
    57  	defer kt.mutex.Unlock()
    58  	kt.stagedTransport = transport
    59  	return transport, nil
    60  }
    61  
    62  // IsConnected is an implementation of the ConnectionTransport interface.
    63  func (kt *SharedKeybaseTransport) IsConnected() bool {
    64  	kt.mutex.Lock()
    65  	defer kt.mutex.Unlock()
    66  	return kt.transport != nil && kt.transport.IsConnected()
    67  }
    68  
    69  // Finalize is an implementation of the ConnectionTransport interface.
    70  func (kt *SharedKeybaseTransport) Finalize() {
    71  	kt.mutex.Lock()
    72  	defer kt.mutex.Unlock()
    73  	kt.transport = kt.stagedTransport
    74  	kt.stagedTransport = nil
    75  }
    76  
    77  // Close is an implementation of the ConnectionTransport interface.
    78  func (kt *SharedKeybaseTransport) Close() {
    79  	// Since this is a shared connection, do nothing.
    80  }