github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/transport/handlers.go (about)

     1  // Package transport provides long-lived http/tcp connections for
     2  // intra-cluster communications (see README for details and usage example).
     3  /*
     4   * Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
     5   */
     6  package transport
     7  
     8  import (
     9  	"fmt"
    10  	"sync"
    11  
    12  	"github.com/NVIDIA/aistore/cmn/cos"
    13  )
    14  
    15  // Rx demux -------------------------------
    16  
    17  const (
    18  	numHmaps = 16
    19  	mskHmaps = numHmaps - 1
    20  
    21  	numOld = 32
    22  )
    23  
    24  type hmap map[string]handler
    25  
    26  type (
    27  	errTrname struct {
    28  		name string
    29  	}
    30  	errDuplicateTrname      struct{ errTrname }
    31  	errUnknownTrname        struct{ errTrname }
    32  	errAlreadyClosedTrname  struct{ errTrname }
    33  	errAlreadyRemovedTrname struct{ errTrname }
    34  )
    35  
    36  var (
    37  	hmaps [numHmaps]hmap // current (active) Rx endpoints
    38  	hmtxs [numHmaps]sync.Mutex
    39  
    40  	old    [numOld]string // a limited pool of the most recently closed Rx endpoints
    41  	oldIdx int
    42  	oldMtx sync.Mutex
    43  )
    44  
    45  func _idx(trname string) byte {
    46  	l := len(trname)
    47  	b := trname[l-1]
    48  	if l >= cos.LenShortID {
    49  		return (-b ^ trname[l-2]) & mskHmaps
    50  	}
    51  	return (b ^ trname[0]) & mskHmaps
    52  }
    53  
    54  func oget(trname string) (h handler, err error) {
    55  	i := _idx(trname)
    56  	hmtxs[i].Lock()
    57  	hmap := hmaps[i]
    58  	h, ok := hmap[trname]
    59  	hmtxs[i].Unlock()
    60  	if ok {
    61  		return
    62  	}
    63  
    64  	oldMtx.Lock()
    65  	err = _lookup(trname)
    66  	oldMtx.Unlock()
    67  	return
    68  }
    69  
    70  func _lookup(trname string) error {
    71  	for j := range numOld {
    72  		if old[j] == trname {
    73  			return &errAlreadyClosedTrname{errTrname{trname}}
    74  		}
    75  	}
    76  	return &errUnknownTrname{errTrname{trname}}
    77  }
    78  
    79  func oput(trname string, h handler) (err error) {
    80  	i := _idx(trname)
    81  	hmtxs[i].Lock()
    82  	hmap := hmaps[i]
    83  	if _, ok := hmap[trname]; ok {
    84  		err = &errDuplicateTrname{errTrname{trname}}
    85  	} else {
    86  		hmap[trname] = h
    87  	}
    88  	hmtxs[i].Unlock()
    89  	return
    90  }
    91  
    92  // plus, hk.Unreg
    93  func odel(trname string) (err error) {
    94  	i := _idx(trname)
    95  	hmtxs[i].Lock()
    96  	hmap := hmaps[i]
    97  	h, ok := hmap[trname]
    98  	if !ok {
    99  		hmtxs[i].Unlock()
   100  		return &errAlreadyRemovedTrname{errTrname{trname}}
   101  	}
   102  
   103  	delete(hmap, trname)
   104  	hmtxs[i].Unlock()
   105  
   106  	h.unreg()
   107  
   108  	oldMtx.Lock()
   109  	old[oldIdx] = trname
   110  	oldIdx++
   111  	if oldIdx >= numOld {
   112  		oldIdx = 0
   113  	}
   114  	oldMtx.Unlock()
   115  	return
   116  }
   117  
   118  //
   119  // Rx errors
   120  //
   121  
   122  func IsErrDuplicateTrname(e error) bool {
   123  	_, ok := e.(*errDuplicateTrname)
   124  	return ok
   125  }
   126  
   127  const fmtep = " transport endpoint %q"
   128  
   129  func (e *errDuplicateTrname) Error() string      { return fmt.Sprintf("duplicate"+fmtep, e.name) }
   130  func (e *errUnknownTrname) Error() string        { return fmt.Sprintf("unknown"+fmtep, e.name) }
   131  func (e *errAlreadyClosedTrname) Error() string  { return fmt.Sprintf("already closed"+fmtep, e.name) }
   132  func (e *errAlreadyRemovedTrname) Error() string { return fmt.Sprintf("already removed"+fmtep, e.name) } // unexpected