module SyncWrap::ZoneBalancer

Utility for balancing new hosts accross multiple (AWS) availability zones for fault tolarance.

Public Class Methods

next_zone( space, zones, roles = [] ) click to toggle source

Return the next best zone from zones Array<String>, preferring the least frequent :availability_zone of existing hosts in the specified space and roles (Array<Symbol>, if empty all hosts).

# File lib/syncwrap/zone_balancer.rb, line 36
def self.next_zone( space, zones, roles = [] )
  if zones
    hosts = filter_hosts( space.hosts, roles )
    zfreqs = {}
    zones.each { |z| zfreqs[z] = 0 }
    czones = hosts.map { |h| h[:availability_zone] }.compact
    czones.each { |z| zfreqs[z] += 1 if zfreqs.has_key?( z ) }

    # Sort by ascending frequency (lowest first). Keep order stable
    # from original zones, when frequency tied.
    # Return the first (least frequent, zones stable) zone.
    n = 0
    zfreqs.sort_by { |_,f| [ f, (n+=1) ] }.first[0]
  end
end
zone( zones, roles ) click to toggle source

Returns a ruby Proc which when called will return the best pick of availability zone, via ::next_zone. This variant uses SyncWrap::Space.current within a SyncWrap::Space#with block.

# File lib/syncwrap/zone_balancer.rb, line 26
def self.zone( zones, roles )
  space = Space.current
  lambda do
    next_zone( space, zones, roles )
  end
end