getReplica returns least loaded + round-robin replica from the cluster. Always returns non-nil.
()
| 833 | // |
| 834 | // Always returns non-nil. |
| 835 | func (c *cluster) getReplica() *replica { |
| 836 | idx := atomic.AddUint32(&c.nextReplicaIdx, 1) |
| 837 | n := uint32(len(c.replicas)) |
| 838 | if n == 1 { |
| 839 | return c.replicas[0] |
| 840 | } |
| 841 | |
| 842 | idx %= n |
| 843 | r := c.replicas[idx] |
| 844 | reqs := r.load() |
| 845 | |
| 846 | // Set least priority to inactive replica. |
| 847 | if !r.isActive() { |
| 848 | reqs = ^uint32(0) |
| 849 | } |
| 850 | |
| 851 | if reqs == 0 { |
| 852 | return r |
| 853 | } |
| 854 | |
| 855 | // Scan all the replicas for the least loaded replica. |
| 856 | for i := uint32(1); i < n; i++ { |
| 857 | tmpIdx := (idx + i) % n |
| 858 | tmpR := c.replicas[tmpIdx] |
| 859 | if !tmpR.isActive() { |
| 860 | continue |
| 861 | } |
| 862 | tmpReqs := tmpR.load() |
| 863 | if tmpReqs == 0 { |
| 864 | return tmpR |
| 865 | } |
| 866 | if tmpReqs < reqs { |
| 867 | r = tmpR |
| 868 | reqs = tmpReqs |
| 869 | } |
| 870 | } |
| 871 | // The returned replica may be inactive. This is OK, |
| 872 | // since this means all the replicas are inactive, |
| 873 | // so let's try proxying the request to any replica. |
| 874 | return r |
| 875 | } |
| 876 | |
| 877 | func (c *cluster) getReplicaSticky(sessionId string) *replica { |
| 878 | idx := atomic.AddUint32(&c.nextReplicaIdx, 1) |