go.uber.org/yarpc@v1.72.1/peer/abstractlist/peer.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package abstractlist 22 23 import ( 24 "go.uber.org/yarpc/api/peer" 25 ) 26 27 var _ peer.Peer = (*peerFacade)(nil) 28 29 // peerFacade captures a peer and its corresponding Subscriber, and serves as a 30 // Peer by proxy. 31 // This allows a transport to send connection status changes into a peer list 32 // without the list having to look them up by their identifier every time. 33 // It also allows the list to retain a single onFinish closure for the lifetime 34 // of the peer, always returning the same func for the peer whenever it is 35 // chosen. 36 type peerFacade struct { 37 list *List 38 id peer.Identifier 39 peer peer.Peer 40 status peer.Status 41 subscriber Subscriber 42 onFinish func(error) 43 } 44 45 // StartRequest is vestigial. 46 // 47 // The peer.Peer interface requires StartRequest because transports used to 48 // track the pending request count. 49 // This responsibility is now handled by the abstract peer list itself. 50 func (pf *peerFacade) StartRequest() {} 51 52 // EndRequest is vestigial. 53 // 54 // The peer.Peer interface requires EndRequest because transports used to 55 // track the pending request count. 56 // This responsibility is now handled by the abstract peer list itself. 57 func (pf *peerFacade) EndRequest() {} 58 59 // NotifyStatusChanged receives status notifications and adjusts the peer list 60 // accodingly. 61 // 62 // Peers that become unavailable are removed from the implementation of the 63 // data structure that tracks candidates for selection. 64 // Peers that become available are restored to that collection. 65 func (pf *peerFacade) NotifyStatusChanged(pid peer.Identifier) { 66 pf.list.lockAndNotifyStatusChanged(pf) 67 } 68 69 func (pf *peerFacade) Identifier() string { 70 // pf.peer is lock safe only because we never write it, not even to nil it 71 // out, even after releasing the peer. 72 return pf.peer.Identifier() 73 } 74 75 func (pf *peerFacade) Status() peer.Status { 76 return pf.list.status(pf) 77 }