Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / lock.py @ 09f54ceb

History | View | Annotate | Download (2.5 kB)

1 57f5ea5c Giorgos Korfiatis
# Copyright 2012-2013 GRNET S.A. All rights reserved.
2 57f5ea5c Giorgos Korfiatis
#
3 57f5ea5c Giorgos Korfiatis
# Redistribution and use in source and binary forms, with or
4 57f5ea5c Giorgos Korfiatis
# without modification, are permitted provided that the following
5 57f5ea5c Giorgos Korfiatis
# conditions are met:
6 57f5ea5c Giorgos Korfiatis
#
7 57f5ea5c Giorgos Korfiatis
#   1. Redistributions of source code must retain the above
8 57f5ea5c Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
9 57f5ea5c Giorgos Korfiatis
#      disclaimer.
10 57f5ea5c Giorgos Korfiatis
#
11 57f5ea5c Giorgos Korfiatis
#   2. Redistributions in binary form must reproduce the above
12 57f5ea5c Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
13 57f5ea5c Giorgos Korfiatis
#      disclaimer in the documentation and/or other materials
14 57f5ea5c Giorgos Korfiatis
#      provided with the distribution.
15 57f5ea5c Giorgos Korfiatis
#
16 57f5ea5c Giorgos Korfiatis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 57f5ea5c Giorgos Korfiatis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 57f5ea5c Giorgos Korfiatis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 57f5ea5c Giorgos Korfiatis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 57f5ea5c Giorgos Korfiatis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 57f5ea5c Giorgos Korfiatis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 57f5ea5c Giorgos Korfiatis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 57f5ea5c Giorgos Korfiatis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 57f5ea5c Giorgos Korfiatis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 57f5ea5c Giorgos Korfiatis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 57f5ea5c Giorgos Korfiatis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 57f5ea5c Giorgos Korfiatis
# POSSIBILITY OF SUCH DAMAGE.
28 57f5ea5c Giorgos Korfiatis
#
29 57f5ea5c Giorgos Korfiatis
# The views and conclusions contained in the software and
30 57f5ea5c Giorgos Korfiatis
# documentation are those of the authors and should not be
31 57f5ea5c Giorgos Korfiatis
# interpreted as representing official policies, either expressed
32 57f5ea5c Giorgos Korfiatis
# or implied, of GRNET S.A.
33 57f5ea5c Giorgos Korfiatis
34 57f5ea5c Giorgos Korfiatis
from django.db import transaction
35 57f5ea5c Giorgos Korfiatis
from django.db import connection
36 57f5ea5c Giorgos Korfiatis
from time import sleep
37 57f5ea5c Giorgos Korfiatis
38 57f5ea5c Giorgos Korfiatis
def with_lock(retries=3, retry_wait=1.0):
39 57f5ea5c Giorgos Korfiatis
    def wrap(func):
40 57f5ea5c Giorgos Korfiatis
        def inner(*args, **kwargs):
41 57f5ea5c Giorgos Korfiatis
42 57f5ea5c Giorgos Korfiatis
            transaction.commit()
43 57f5ea5c Giorgos Korfiatis
44 57f5ea5c Giorgos Korfiatis
            cursor = connection.cursor()
45 57f5ea5c Giorgos Korfiatis
            locked = True
46 57f5ea5c Giorgos Korfiatis
            try:
47 57f5ea5c Giorgos Korfiatis
                while 1:
48 57f5ea5c Giorgos Korfiatis
                    cursor.execute("SELECT pg_try_advisory_lock(1)")
49 57f5ea5c Giorgos Korfiatis
                    r = cursor.fetchone()
50 57f5ea5c Giorgos Korfiatis
                    if r is None:
51 57f5ea5c Giorgos Korfiatis
                        m = "Impossible"
52 57f5ea5c Giorgos Korfiatis
                        raise AssertionError(m)
53 57f5ea5c Giorgos Korfiatis
                    locked = r[0]
54 57f5ea5c Giorgos Korfiatis
                    if locked:
55 57f5ea5c Giorgos Korfiatis
                        break
56 57f5ea5c Giorgos Korfiatis
57 57f5ea5c Giorgos Korfiatis
                    retries -= 1
58 57f5ea5c Giorgos Korfiatis
                    if retries <= 0:
59 57f5ea5c Giorgos Korfiatis
                        return False
60 57f5ea5c Giorgos Korfiatis
                    sleep(retry_wait)
61 57f5ea5c Giorgos Korfiatis
62 57f5ea5c Giorgos Korfiatis
                return func(*args, **kwargs)
63 57f5ea5c Giorgos Korfiatis
64 57f5ea5c Giorgos Korfiatis
            finally:
65 57f5ea5c Giorgos Korfiatis
                if locked:
66 57f5ea5c Giorgos Korfiatis
                    cursor.execute("SELECT pg_advisory_unlock(1)")
67 57f5ea5c Giorgos Korfiatis
                    cursor.fetchall()
68 57f5ea5c Giorgos Korfiatis
        return inner
69 57f5ea5c Giorgos Korfiatis
    return wrap