#!/usr/bin/env python3 # Copyright 2014 Brett Slatkin, Pearson Education Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Preamble to mimick book environment import logging from pprint import pprint from sys import stdout as STDOUT # Example 1 from datetime import datetime, timedelta class Bucket(object): def __init__(self, period): self.period_delta = timedelta(seconds=period) self.reset_time = datetime.now() self.quota = 0 def __repr__(self): return 'Bucket(quota=%d)' % self.quota bucket = Bucket(60) print(bucket) # Example 2 def fill(bucket, amount): now = datetime.now() if now - bucket.reset_time > bucket.period_delta: bucket.quota = 0 bucket.reset_time = now bucket.quota += amount # Example 3 def deduct(bucket, amount): now = datetime.now() if now - bucket.reset_time > bucket.period_delta: return False if bucket.quota - amount < 0: return False bucket.quota -= amount return True # Example 4 bucket = Bucket(60) fill(bucket, 100) print(bucket) # Example 5 if deduct(bucket, 99): print('Had 99 quota') else: print('Not enough for 99 quota') print(bucket) # Example 6 if deduct(bucket, 3): print('Had 3 quota') else: print('Not enough for 3 quota') print(bucket) # Example 7 class Bucket(object): def __init__(self, period): self.period_delta = timedelta(seconds=period) self.reset_time = datetime.now() self.max_quota = 0 self.quota_consumed = 0 def __repr__(self): return ('Bucket(max_quota=%d, quota_consumed=%d)' % (self.max_quota, self.quota_consumed)) # Example 8 @property def quota(self): return self.max_quota - self.quota_consumed # Example 9 @quota.setter def quota(self, amount): delta = self.max_quota - amount if amount == 0: # Quota being reset for a new period self.quota_consumed = 0 self.max_quota = 0 elif delta < 0: # Quota being filled for the new period assert self.quota_consumed == 0 self.max_quota = amount else: # Quota being consumed during the period assert self.max_quota >= self.quota_consumed self.quota_consumed += delta # Example 10 bucket = Bucket(60) print('Initial', bucket) fill(bucket, 100) print('Filled', bucket) if deduct(bucket, 99): print('Had 99 quota') else: print('Not enough for 99 quota') print('Now', bucket) if deduct(bucket, 3): print('Had 3 quota') else: print('Not enough for 3 quota') print('Still', bucket)