diff options
| author | Soren Hansen <soren@linux2go.dk> | 2011-02-28 12:37:02 +0100 |
|---|---|---|
| committer | Soren Hansen <soren@linux2go.dk> | 2011-02-28 12:37:02 +0100 |
| commit | 8b3e9ad11c2f5c425701f1eb4abb7b3f577ae1cc (patch) | |
| tree | e11aa4a0eb4188b998b91c65970682a5c61ac0b6 | |
| parent | edf5da85648659b1a7ad105248d69ef9f8c977e4 (diff) | |
| download | nova-8b3e9ad11c2f5c425701f1eb4abb7b3f577ae1cc.tar.gz nova-8b3e9ad11c2f5c425701f1eb4abb7b3f577ae1cc.tar.xz nova-8b3e9ad11c2f5c425701f1eb4abb7b3f577ae1cc.zip | |
Add utils.synchronized decorator to allow for synchronising method entrance across multiple workers on the same host.
| -rw-r--r-- | nova/tests/test_misc.py | 37 | ||||
| -rw-r--r-- | nova/utils.py | 11 |
2 files changed, 47 insertions, 1 deletions
diff --git a/nova/tests/test_misc.py b/nova/tests/test_misc.py index e6da6112a..154b6fae6 100644 --- a/nova/tests/test_misc.py +++ b/nova/tests/test_misc.py @@ -14,10 +14,14 @@ # License for the specific language governing permissions and limitations # under the License. +from datetime import datetime +import errno import os +import select +import time from nova import test -from nova.utils import parse_mailmap, str_dict_replace +from nova.utils import parse_mailmap, str_dict_replace, synchronized class ProjectTestCase(test.TestCase): @@ -55,3 +59,34 @@ class ProjectTestCase(test.TestCase): '%r not listed in Authors' % missing) finally: tree.unlock() + + +class LockTestCase(test.TestCase): + def test_synchronized(self): + rpipe, wpipe = os.pipe() + pid = os.fork() + if pid > 0: + os.close(wpipe) + + @synchronized('testlock') + def f(): + rfds, _, __ = select.select([rpipe], [], [], 1) + self.assertEquals(len(rfds), 0, "The other process, which was" + " supposed to be locked, " + "wrote on its end of the " + "pipe") + os.close(rpipe) + + f() + else: + os.close(rpipe) + + @synchronized('testlock') + def g(): + try: + os.write(wpipe, "foo") + except OSError, e: + self.assertEquals(e.errno, errno.EPIPE) + return + g() + os._exit(0) diff --git a/nova/utils.py b/nova/utils.py index 0cf91e0cc..cb1ea5a7d 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -25,6 +25,7 @@ import base64 import datetime import inspect import json +import lockfile import os import random import socket @@ -491,6 +492,16 @@ def loads(s): return json.loads(s) +def synchronized(name): + def wrap(f): + def inner(*args, **kwargs): + lock = lockfile.FileLock('nova-%s.lock' % name) + with lock: + return f(*args, **kwargs) + return inner + return wrap + + def ensure_b64_encoding(val): """Safety method to ensure that values expected to be base64-encoded actually are. If they are, the value is returned unchanged. Otherwise, |
