bestMappings takes a set of mappings and resolves the best set of nodes. We may get several mappings for a particular connection, from different coordinators in the distributed system. Furthermore, some coordinators might be considered invalid on account of missing heartbeats. We take the most re
(mappings []mapping)
| 775 | // might be considered invalid on account of missing heartbeats. We take the most recent mapping from a valid |
| 776 | // coordinator as the "best" mapping. |
| 777 | func (m *mapper) bestMappings(mappings []mapping) map[uuid.UUID]mapping { |
| 778 | mappings = m.heartbeats.filter(mappings) |
| 779 | best := make(map[uuid.UUID]mapping, len(mappings)) |
| 780 | for _, mpng := range mappings { |
| 781 | bestM, ok := best[mpng.peer] |
| 782 | switch { |
| 783 | case !ok: |
| 784 | // no current best |
| 785 | best[mpng.peer] = mpng |
| 786 | |
| 787 | // NODE always beats LOST mapping, since the LOST could be from a coordinator that's |
| 788 | // slow updating the DB, and the peer has reconnected to a different coordinator and |
| 789 | // given a NODE mapping. |
| 790 | case bestM.kind == proto.CoordinateResponse_PeerUpdate_LOST && mpng.kind == proto.CoordinateResponse_PeerUpdate_NODE: |
| 791 | best[mpng.peer] = mpng |
| 792 | case mpng.updatedAt.After(bestM.updatedAt) && mpng.kind == proto.CoordinateResponse_PeerUpdate_NODE: |
| 793 | // newer, and it's a NODE update. |
| 794 | best[mpng.peer] = mpng |
| 795 | } |
| 796 | } |
| 797 | return best |
| 798 | } |
| 799 | |
| 800 | func (m *mapper) bestToUpdate(best map[uuid.UUID]mapping) *proto.CoordinateResponse { |
| 801 | resp := new(proto.CoordinateResponse) |