def collect_usage(self, tenant, mutex, end=None): # Collects usage for a given tenant from when they were last collected, # up to the given end, and breaks the range into one hour windows. end = end or datetime.utcnow() time_label = TimeLabel(tenant.last_collected + timedelta(minutes=1)) end_time_label = TimeLabel(end) usage = {} logbook.info( 'collect_usage for {}, from {} till {} (last_collected: {})', tenant, time_label, end_time_label, tenant.last_collected) customer = Customer.get_by_tenant_id(tenant.tenant_id) if not customer: logbook.error("Customer for tenant {} not found", tenant) return usage while time_label < end_time_label: try: usages = self._collect_usage(tenant, time_label, customer) tenant.last_collected = time_label.datetime_range()[1] if usages: db.session.add(customer) total_cost = customer.calculate_usage_cost(usages) customer.withdraw(total_cost) if not conf.test: db.session.commit() usage[time_label] = [usage.to_dict() for usage in usages], total_cost except Exception: self.errors += 1 import traceback traceback.print_exc() logbook.exception("Usage process failed for {} and {}", tenant, time_label) db.session.rollback() return usage time_label = time_label.next() mutex.update_ttl() return usage
def collect_usage(self, tenant, mutex, end=None): # Collects usage for a given tenant from when they were last collected, # up to the given end, and breaks the range into one hour windows. end = end or datetime.utcnow() time_label = TimeLabel(tenant.last_collected + timedelta(minutes=1)) end_time_label = TimeLabel(end) usage = {} logbook.info('collect_usage for {}, from {} till {} (last_collected: {})', tenant, time_label, end_time_label, tenant.last_collected) customer = Customer.get_by_tenant_id(tenant.tenant_id) if not customer: logbook.error("Customer for tenant {} not found", tenant) return usage while time_label < end_time_label: try: usages = self._collect_usage(tenant, time_label, customer) tenant.last_collected = time_label.datetime_range()[1] if usages: db.session.add(customer) total_cost = customer.calculate_usage_cost(usages) customer.withdraw(total_cost) if not conf.test: db.session.commit() usage[time_label] = [usage.to_dict() for usage in usages], total_cost except Exception: self.errors += 1 import traceback traceback.print_exc() logbook.exception("Usage process failed for {} and {}", tenant, time_label) db.session.rollback() return usage time_label = time_label.next() mutex.update_ttl() return usage