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