vitess.io/vitess@v0.16.2/go/vt/vttablet/tabletmanager/rpc_server.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package tabletmanager
    18  
    19  import (
    20  	"fmt"
    21  
    22  	"vitess.io/vitess/go/vt/vterrors"
    23  
    24  	"context"
    25  
    26  	"vitess.io/vitess/go/tb"
    27  	"vitess.io/vitess/go/vt/callinfo"
    28  	"vitess.io/vitess/go/vt/log"
    29  	"vitess.io/vitess/go/vt/topo/topoproto"
    30  )
    31  
    32  // This file contains the RPC method helpers for the tablet manager.
    33  
    34  //
    35  // Utility functions for RPC service
    36  //
    37  
    38  // lock is used at the beginning of an RPC call, to acquire the
    39  // action semaphore. It returns ctx.Err() if the context expires.
    40  func (tm *TabletManager) lock(ctx context.Context) error {
    41  	if tm.actionSema.AcquireContext(ctx) {
    42  		return nil
    43  	}
    44  	return ctx.Err()
    45  }
    46  
    47  // tryLock will return immediately, true on success and false on failure.
    48  func (tm *TabletManager) tryLock() bool {
    49  	return tm.actionSema.TryAcquire()
    50  }
    51  
    52  // unlock is the symmetrical action to lock.
    53  func (tm *TabletManager) unlock() {
    54  	tm.actionSema.Release()
    55  }
    56  
    57  // HandleRPCPanic is part of the RPCTM interface.
    58  func (tm *TabletManager) HandleRPCPanic(ctx context.Context, name string, args, reply any, verbose bool, err *error) {
    59  	// panic handling
    60  	if x := recover(); x != nil {
    61  		log.Errorf("TabletManager.%v(%v) on %v panic: %v\n%s", name, args, topoproto.TabletAliasString(tm.tabletAlias), x, tb.Stack(4))
    62  		*err = fmt.Errorf("caught panic during %v: %v", name, x)
    63  		return
    64  	}
    65  
    66  	// quick check for fast path
    67  	if !verbose && *err == nil {
    68  		return
    69  	}
    70  
    71  	// we gotta log something, get the source
    72  	from := ""
    73  	ci, ok := callinfo.FromContext(ctx)
    74  	if ok {
    75  		from = ci.Text()
    76  	}
    77  
    78  	if *err != nil {
    79  		// error case
    80  		log.Warningf("TabletManager.%v(%v)(on %v from %v) error: %v", name, args, topoproto.TabletAliasString(tm.tabletAlias), from, (*err).Error())
    81  		*err = vterrors.Wrapf(*err, "TabletManager.%v on %v error: %v", name, topoproto.TabletAliasString(tm.tabletAlias), (*err).Error())
    82  	} else {
    83  		// success case
    84  		log.Infof("TabletManager.%v(%v)(on %v from %v): %#v", name, args, topoproto.TabletAliasString(tm.tabletAlias), from, reply)
    85  	}
    86  }
    87  
    88  // RegisterTabletManager is used to delay registration of RPC servers until we have all the objects.
    89  type RegisterTabletManager func(*TabletManager)
    90  
    91  // RegisterTabletManagers is a list of functions to call when the delayed registration is triggered.
    92  var RegisterTabletManagers []RegisterTabletManager
    93  
    94  // registerTabletManager will register all the instances.
    95  func (tm *TabletManager) registerTabletManager() {
    96  	for _, f := range RegisterTabletManagers {
    97  		f(tm)
    98  	}
    99  }