简体   繁体   中英

Rate limiting generator wrapper?

Lets say I have something like

for user in users:
     send_email(user)

But since I want to reduce congestion, I want something like

for user in rate_limit(per_min=50, users):
     send_email(user)

Where the rate_limit function simply sleeps and starts yielding from users again once the rate limit as been reached.

# something like this, where it just sleeps (until next min/sec cycle) 
# once the number of iterations per_min or per_sec have been achieved.

def rate_limit(per_min=None, per_sec=None, objects):
    ???

Problem is I have no clue how to preserve state (in the sense of time elapsed/emails sent) in this form.

Does anyone have any ideas?

You're probably looking for time.sleep() :

  1. Yield an object
  2. Sleep
  3. Repeat from step 1

For example:

import time

def rate_limit(objects, per_min=None):
    sleep_time = 60 / per_min if per_min else 0
    for obj in objects:
        yield obj
        time.sleep(sleep_time)

Problem is I have no clue how to preserve state (in the sense of time elapsed/emails sent) in this form.

This will automatically preserver the state, as yield simply pauses the function and continues after the function is called again. If you want to know the spent time and number of mails sent, you can simply add a counter:

def rate_limit(objects, per_min=None):
    sleep_time = 60 / per_min if per_min else 0
    for count, obj in enumerate(objects):
        yield obj
        print('Sent email {0} at {1} seconds.'.format(count, count * sleep_time))
        time.sleep(sleep_time)

只需使用time.sleep这会将当前线程挂起给定的秒数。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM