A subclass of :class:`.LoadBalancingPolicy` which evenly distributes queries across all nodes in the cluster, regardless of what datacenter the nodes may be in.
| 153 | |
| 154 | |
| 155 | class RoundRobinPolicy(LoadBalancingPolicy): |
| 156 | """ |
| 157 | A subclass of :class:`.LoadBalancingPolicy` which evenly |
| 158 | distributes queries across all nodes in the cluster, |
| 159 | regardless of what datacenter the nodes may be in. |
| 160 | """ |
| 161 | _live_hosts = frozenset(()) |
| 162 | _position = 0 |
| 163 | |
| 164 | def populate(self, cluster, hosts): |
| 165 | self._live_hosts = frozenset(hosts) |
| 166 | if len(hosts) > 1: |
| 167 | self._position = randint(0, len(hosts) - 1) |
| 168 | |
| 169 | def distance(self, host): |
| 170 | return HostDistance.LOCAL |
| 171 | |
| 172 | def make_query_plan(self, working_keyspace=None, query=None): |
| 173 | # not thread-safe, but we don't care much about lost increments |
| 174 | # for the purposes of load balancing |
| 175 | pos = self._position |
| 176 | self._position += 1 |
| 177 | |
| 178 | hosts = self._live_hosts |
| 179 | length = len(hosts) |
| 180 | if length: |
| 181 | pos %= length |
| 182 | return islice(cycle(hosts), pos, pos + length) |
| 183 | else: |
| 184 | return [] |
| 185 | |
| 186 | def on_up(self, host): |
| 187 | with self._hosts_lock: |
| 188 | self._live_hosts = self._live_hosts.union((host, )) |
| 189 | |
| 190 | def on_down(self, host): |
| 191 | with self._hosts_lock: |
| 192 | self._live_hosts = self._live_hosts.difference((host, )) |
| 193 | |
| 194 | def on_add(self, host): |
| 195 | with self._hosts_lock: |
| 196 | self._live_hosts = self._live_hosts.union((host, )) |
| 197 | |
| 198 | def on_remove(self, host): |
| 199 | with self._hosts_lock: |
| 200 | self._live_hosts = self._live_hosts.difference((host, )) |
| 201 | |
| 202 | |
| 203 | class DCAwareRoundRobinPolicy(LoadBalancingPolicy): |
no outgoing calls