OLD | NEW |
(Empty) | |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 from datetime import datetime |
| 6 import logging |
| 7 import random |
| 8 import time |
| 9 |
| 10 from google.appengine.api import memcache |
| 11 |
| 12 |
| 13 _MEMCACHE_MASTER_DOWNLOAD_LOCK = 'master-download-lock-%s' |
| 14 _MEMCACHE_MASTER_DOWNLOAD_EXPIRATION_SECONDS = 60 * 60 |
| 15 _DOWNLOAD_INTERVAL_SECONDS = 5 |
| 16 |
| 17 |
| 18 def WaitUntilDownloadAllowed( |
| 19 master_name, timeout_seconds=90): # pragma: no cover |
| 20 """Waits until next download from the specified master is allowed. |
| 21 |
| 22 Returns: |
| 23 True if download is allowed to proceed. |
| 24 False if download is not still allowed when the given timeout occurs. |
| 25 """ |
| 26 client = memcache.Client() |
| 27 key = _MEMCACHE_MASTER_DOWNLOAD_LOCK % master_name |
| 28 |
| 29 deadline = time.time() + timeout_seconds |
| 30 while True: |
| 31 info = client.gets(key) |
| 32 if not info or time.time() - info['time'] >= _DOWNLOAD_INTERVAL_SECONDS: |
| 33 new_info = { |
| 34 'time': time.time() |
| 35 } |
| 36 if not info: |
| 37 success = client.add( |
| 38 key, new_info, time=_MEMCACHE_MASTER_DOWNLOAD_EXPIRATION_SECONDS) |
| 39 else: |
| 40 success = client.cas( |
| 41 key, new_info, time=_MEMCACHE_MASTER_DOWNLOAD_EXPIRATION_SECONDS) |
| 42 |
| 43 if success: |
| 44 logging.info('Download from %s is allowed. Waited %s seconds.', |
| 45 master_name, (time.time() + timeout_seconds - deadline)) |
| 46 return True |
| 47 |
| 48 if time.time() > deadline: |
| 49 logging.info('Download from %s is not allowed. Waited %s seconds.', |
| 50 master_name, timeout_seconds) |
| 51 return False |
| 52 |
| 53 logging.info('Waiting to download from %s', master_name) |
| 54 time.sleep(_DOWNLOAD_INTERVAL_SECONDS + random.random()) |
OLD | NEW |