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