def claim_sites(self, n=1): result = ( self.rr.table('sites').get_all( r.args( r.db(self.rr.dbname).table( 'sites', read_mode='majority').between( ['ACTIVE', r.minval], ['ACTIVE', r.maxval], index='sites_last_disclaimed').order_by( r.desc('claimed'), 'last_disclaimed'). fold({}, lambda acc, site: acc.merge( r.branch( site.has_fields('job_id'), r.object( site['job_id'].coerce_to('string'), acc[ site['job_id'].coerce_to('string')]. default(0).add(1)), {})), emit=lambda acc, site, new_acc: r.branch( r.and_( r.or_( site['claimed'].not_(), site[ 'last_claimed'].lt(r.now().sub(60 * 60 ))), r.or_( site.has_fields('max_claimed_sites').not_( ), new_acc[site['job_id'].coerce_to( 'string')].le(site['max_claimed_sites' ]))), [site['id']], [])).limit(n))). update( # try to avoid a race condition resulting in multiple # brozzler-workers claiming the same site # see https://github.com/rethinkdb/rethinkdb/issues/3235#issuecomment-60283038 r.branch( r.or_(r.row['claimed'].not_(), r.row['last_claimed'].lt(r.now().sub(60 * 60))), { 'claimed': True, 'last_claimed': r.now() }, {}), return_changes=True)).run() self._vet_result(result, replaced=list(range(n + 1)), unchanged=list(range(n + 1))) sites = [] for i in range(result["replaced"]): if result["changes"][i]["old_val"]["claimed"]: self.logger.warn( "re-claimed site that was still marked 'claimed' " "because it was last claimed a long time ago " "at %s, and presumably some error stopped it from " "being disclaimed", result["changes"][i]["old_val"]["last_claimed"]) site = brozzler.Site(self.rr, result["changes"][i]["new_val"]) sites.append(site) if sites: return sites else: raise brozzler.NothingToClaim
def claim_sites(self, n=1): self.logger.trace('claiming up to %s sites to brozzle', n) result = ( self.rr.table('sites').get_all(r.args( r.db(self.rr.dbname).table('sites', read_mode='majority') .between( ['ACTIVE', r.minval], ['ACTIVE', r.maxval], index='sites_last_disclaimed') .order_by(r.desc('claimed'), 'last_disclaimed') .fold( {}, lambda acc, site: acc.merge( r.branch( site.has_fields('job_id'), r.object( site['job_id'].coerce_to('string'), acc[site['job_id'].coerce_to('string')].default(0).add(1)), {})), emit=lambda acc, site, new_acc: r.branch( r.and_( r.or_( site['claimed'].not_(), site['last_claimed'].lt(r.now().sub(60*60))), r.or_( site.has_fields('max_claimed_sites').not_(), new_acc[site['job_id'].coerce_to('string')].le(site['max_claimed_sites']))), [site['id']], [])) .limit(n))) .update( # try to avoid a race condition resulting in multiple # brozzler-workers claiming the same site # see https://github.com/rethinkdb/rethinkdb/issues/3235#issuecomment-60283038 r.branch( r.or_( r.row['claimed'].not_(), r.row['last_claimed'].lt(r.now().sub(60*60))), {'claimed': True, 'last_claimed': r.now()}, {}), return_changes=True)).run() self._vet_result( result, replaced=list(range(n+1)), unchanged=list(range(n+1))) sites = [] for i in range(result["replaced"]): if result["changes"][i]["old_val"]["claimed"]: self.logger.warn( "re-claimed site that was still marked 'claimed' " "because it was last claimed a long time ago " "at %s, and presumably some error stopped it from " "being disclaimed", result["changes"][i]["old_val"]["last_claimed"]) site = brozzler.Site(self.rr, result["changes"][i]["new_val"]) sites.append(site) self.logger.debug('claimed %s sites', len(sites)) if sites: return sites else: raise brozzler.NothingToClaim