(self)
| 247 | ) |
| 248 | |
| 249 | def get_value(self): |
| 250 | self.namespace.acquire_read_lock() |
| 251 | try: |
| 252 | has_value = self.has_value() |
| 253 | if has_value: |
| 254 | try: |
| 255 | stored, expired, value = self._get_value() |
| 256 | if not self._is_expired(stored, expired): |
| 257 | return value |
| 258 | except KeyError: |
| 259 | # guard against un-mutexed backends raising KeyError |
| 260 | has_value = False |
| 261 | |
| 262 | if not self.createfunc: |
| 263 | raise KeyError(self.key) |
| 264 | finally: |
| 265 | self.namespace.release_read_lock() |
| 266 | |
| 267 | has_createlock = False |
| 268 | creation_lock = self.namespace.get_creation_lock(self.key) |
| 269 | if has_value: |
| 270 | if not creation_lock.acquire(wait=False): |
| 271 | debug("get_value returning old value while new one is created") |
| 272 | return value |
| 273 | else: |
| 274 | debug("lock_creatfunc (didnt wait)") |
| 275 | has_createlock = True |
| 276 | |
| 277 | if not has_createlock: |
| 278 | debug("lock_createfunc (waiting)") |
| 279 | creation_lock.acquire() |
| 280 | debug("lock_createfunc (waited)") |
| 281 | |
| 282 | try: |
| 283 | # see if someone created the value already |
| 284 | self.namespace.acquire_read_lock() |
| 285 | try: |
| 286 | if self.has_value(): |
| 287 | try: |
| 288 | stored, expired, value = self._get_value() |
| 289 | if not self._is_expired(stored, expired): |
| 290 | return value |
| 291 | except KeyError: |
| 292 | # guard against un-mutexed backends raising KeyError |
| 293 | pass |
| 294 | finally: |
| 295 | self.namespace.release_read_lock() |
| 296 | |
| 297 | debug("get_value creating new value") |
| 298 | v = self.createfunc() |
| 299 | self.set_value(v) |
| 300 | return v |
| 301 | finally: |
| 302 | creation_lock.release() |
| 303 | debug("released create lock") |
| 304 | |
| 305 | def _get_value(self): |
| 306 | value = self.namespace[self.key] |
no test coverage detected