Show More
@@ -17,16 +17,24 b'' | |||
|
17 | 17 | # This program is dual-licensed. If you wish to learn more about the |
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | import time | |
|
21 | import errno | |
|
22 | import logging | |
|
23 | ||
|
24 | import gevent | |
|
20 | 25 | |
|
21 | 26 | from dogpile.cache.backends import memory as memory_backend |
|
22 | 27 | from dogpile.cache.backends import file as file_backend |
|
23 | 28 | from dogpile.cache.backends import redis as redis_backend |
|
24 | from dogpile.cache.backends.file import NO_VALUE, compat | |
|
29 | from dogpile.cache.backends.file import NO_VALUE, compat, FileLock | |
|
30 | from dogpile.cache.util import memoized_property | |
|
25 | 31 | |
|
26 | 32 | from rhodecode.lib.memory_lru_debug import LRUDict |
|
27 | 33 | |
|
28 | 34 | _default_max_size = 1024 |
|
29 | 35 | |
|
36 | log = logging.getLogger(__name__) | |
|
37 | ||
|
30 | 38 | |
|
31 | 39 | class LRUMemoryBackend(memory_backend.MemoryBackend): |
|
32 | 40 | |
@@ -44,9 +52,45 b' class Serializer(object):' | |||
|
44 | 52 | return compat.pickle.loads(value) |
|
45 | 53 | |
|
46 | 54 | |
|
55 | class CustomLockFactory(FileLock): | |
|
56 | ||
|
57 | @memoized_property | |
|
58 | def _module(self): | |
|
59 | import fcntl | |
|
60 | flock_org = fcntl.flock | |
|
61 | ||
|
62 | def gevent_flock(fd, operation): | |
|
63 | """ | |
|
64 | Gevent compatible flock | |
|
65 | """ | |
|
66 | # set non-blocking, this will cause an exception if we cannot acquire a lock | |
|
67 | operation |= fcntl.LOCK_NB | |
|
68 | start_lock_time = time.time() | |
|
69 | timeout = 60 * 5 # 5min | |
|
70 | while True: | |
|
71 | try: | |
|
72 | flock_org(fd, operation) | |
|
73 | # lock has been acquired | |
|
74 | break | |
|
75 | except (OSError, IOError) as e: | |
|
76 | # raise on other errors than Resource temporarily unavailable | |
|
77 | if e.errno != errno.EAGAIN: | |
|
78 | raise | |
|
79 | elif (time.time() - start_lock_time) > timeout: | |
|
80 | # waited to much time on a lock, better fail than loop for ever | |
|
81 | raise | |
|
82 | ||
|
83 | log.debug('Failed to acquire lock, retry in 0.1') | |
|
84 | gevent.sleep(0.1) | |
|
85 | ||
|
86 | fcntl.flock = gevent_flock | |
|
87 | return fcntl | |
|
88 | ||
|
89 | ||
|
47 | 90 | class FileNamespaceBackend(Serializer, file_backend.DBMBackend): |
|
48 | 91 | |
|
49 | 92 | def __init__(self, arguments): |
|
93 | arguments['lock_factory'] = CustomLockFactory | |
|
50 | 94 | super(FileNamespaceBackend, self).__init__(arguments) |
|
51 | 95 | |
|
52 | 96 | def list_keys(self, prefix=''): |
General Comments 0
You need to be logged in to leave comments.
Login now