| Index: appengine/findit/waterfall/lock_util.py
|
| diff --git a/appengine/findit/waterfall/lock_util.py b/appengine/findit/waterfall/lock_util.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a12634491e37d60b3421b164f8596f222e5a4f9b
|
| --- /dev/null
|
| +++ b/appengine/findit/waterfall/lock_util.py
|
| @@ -0,0 +1,54 @@
|
| +# Copyright 2014 The Chromium Authors. All rights reserved.
|
| +# Use of this source code is governed by a BSD-style license that can be
|
| +# found in the LICENSE file.
|
| +
|
| +from datetime import datetime
|
| +import logging
|
| +import random
|
| +import time
|
| +
|
| +from google.appengine.api import memcache
|
| +
|
| +
|
| +_MEMCACHE_MASTER_DOWNLOAD_LOCK = 'master-download-lock-%s'
|
| +_MEMCACHE_MASTER_DOWNLOAD_EXPIRATION_SECONDS = 60 * 60
|
| +_DOWNLOAD_INTERVAL_SECONDS = 5
|
| +
|
| +
|
| +def WaitUntilDownloadAllowed(
|
| + master_name, timeout_seconds=90): # pragma: no cover
|
| + """Waits until next download from the specified master is allowed.
|
| +
|
| + Returns:
|
| + True if download is allowed to proceed.
|
| + False if download is not still allowed when the given timeout occurs.
|
| + """
|
| + client = memcache.Client()
|
| + key = _MEMCACHE_MASTER_DOWNLOAD_LOCK % master_name
|
| +
|
| + deadline = time.time() + timeout_seconds
|
| + while True:
|
| + info = client.gets(key)
|
| + if not info or time.time() - info['time'] >= _DOWNLOAD_INTERVAL_SECONDS:
|
| + new_info = {
|
| + 'time': time.time()
|
| + }
|
| + if not info:
|
| + success = client.add(
|
| + key, new_info, time=_MEMCACHE_MASTER_DOWNLOAD_EXPIRATION_SECONDS)
|
| + else:
|
| + success = client.cas(
|
| + key, new_info, time=_MEMCACHE_MASTER_DOWNLOAD_EXPIRATION_SECONDS)
|
| +
|
| + if success:
|
| + logging.info('Download from %s is allowed. Waited %s seconds.',
|
| + master_name, (time.time() + timeout_seconds - deadline))
|
| + return True
|
| +
|
| + if time.time() > deadline:
|
| + logging.info('Download from %s is not allowed. Waited %s seconds.',
|
| + master_name, timeout_seconds)
|
| + return False
|
| +
|
| + logging.info('Waiting to download from %s', master_name)
|
| + time.sleep(_DOWNLOAD_INTERVAL_SECONDS + random.random())
|
|
|