Search code examples
pythongoogle-app-enginetimegae-quotas

How to save memcache value till quota is replenished?


In order to send not more than 100 e-mail messages per day, I create the following logic in my application:

  1. all e-mail messages to be sent are stored in Datastore;
  2. there is a cron job, which runs every 15 minutes;
  3. this job is to send e-mail messages from the queue;
  4. prior to reading messages from the Datastore queue, the job reads the value from the memcache (is_todays_quota_exceeded);
  5. if it is not, try to send messages. If successful, update queue status for this message. If it fails with apiproxy_errors.OverQuotaError, write is_todays_quota_exceeded equal to 1.

The problem I have is that I should store memcache value till the end of GAE day (i.e. till the quota is replenished). How can I calculate that in seconds?

Daily quotas are replenished daily at midnight Pacific time.

Upd. I've tried the following:

now = datetime.datetime.now()
current_time = datetime.datetime(year=now.year, month=now.month, day=now.day, hour=now.hour, minute=now.minute, second=now.second)
end_of_today = datetime.datetime(year=now.year, month=now.month, day=now.day, hour=23, minute=59, second=59)
diff = end_of_today - current_time
logging.info(diff.total_seconds())

But it fails at the last line - 'datetime.timedelta' object has no attribute 'total_seconds'. I use Python 2.5, looks like total_seconds was implemented later.

Upd2. The following helps to calculate number of seconds till end of today:

now = datetime.datetime.utcnow()
diff = (23*60*60 + 59*60 + 59*60) - (now.hour*60*60 - now.minute*60 - now.second*60)
logging.info(diff)

Solution

  • You cloud have another cron job that runs before midnight Pacific time every day to reset this value.

    If you want to calculate the end of the day, do something like this:

    >>> from datetime import datetime
    >>> timestamp = datetime.utcnow()
    >>> end_of_day = datetime(year=timestamp.year, month=timestamp.month, day=timestamp.day, hour=23, minute=59, second=59)
    >>> end_of_day
    datetime.datetime(2013, 3, 17, 23, 59, 59)
    

    Or you could simply check if the datetime.utcnow().hour is 0 you know that the day just started and act accordingly.