| 485 | self.running_lock = threading.Lock() |
| 486 | |
| 487 | def __call__(self, *args, **keywords): |
| 488 | key = (args, tuple(keywords.items())) |
| 489 | with self.running_lock: |
| 490 | if not self.running.get(key): |
| 491 | self.running[key] = threading.Lock() |
| 492 | |
| 493 | def update(block=False): |
| 494 | if self.running[key].acquire(block): |
| 495 | try: |
| 496 | self.cache[key] = (self.func(*args, **keywords), time.time()) |
| 497 | finally: |
| 498 | self.running[key].release() |
| 499 | |
| 500 | if key not in self.cache: |
| 501 | update(block=True) |
| 502 | elif self.expires and (time.time() - self.cache[key][1]) > self.expires: |
| 503 | if self.background: |
| 504 | threading.Thread(target=update).start() |
| 505 | else: |
| 506 | update() |
| 507 | return self.cache[key][0] |
| 508 | |
| 509 | |
| 510 | memoize = Memoize |