(self)
| 164 | return found_locks |
| 165 | |
| 166 | def acquire(self): |
| 167 | # goal |
| 168 | # for exclusive lock: there must be only 1 exclusive lock and no other (exclusive or non-exclusive) locks. |
| 169 | # for non-exclusive lock: there can be multiple n-e locks, but there must not exist an exclusive lock. |
| 170 | logger.debug(f"LOCK-ACQUIRE: trying to acquire a lock. exclusive: {self.is_exclusive}.") |
| 171 | started = time.monotonic() |
| 172 | while time.monotonic() - started < self.timeout: |
| 173 | exclusive_locks = self._find_locks(only_exclusive=True) |
| 174 | if len(exclusive_locks) == 0: |
| 175 | # looks like there are no exclusive locks, create our lock. |
| 176 | key = self._create_lock(exclusive=self.is_exclusive, update_last_refresh=True) |
| 177 | # obviously we have a race condition here: other client(s) might have created exclusive |
| 178 | # lock(s) at the same time in parallel. thus we have to check again. |
| 179 | time.sleep( |
| 180 | self.race_recheck_delay |
| 181 | ) # give other clients time to notice our exclusive lock, stop creating theirs |
| 182 | exclusive_locks = self._find_locks(only_exclusive=True) |
| 183 | if self.is_exclusive: |
| 184 | if len(exclusive_locks) == 1 and exclusive_locks[0]["key"] == key: |
| 185 | logger.debug("LOCK-ACQUIRE: we are the only exclusive lock!") |
| 186 | while time.monotonic() - started < self.timeout: |
| 187 | locks = self._find_locks(only_exclusive=False) |
| 188 | if len(locks) == 1 and locks[0]["key"] == key: |
| 189 | logger.debug("LOCK-ACQUIRE: success! no non-exclusive locks are left!") |
| 190 | return self |
| 191 | time.sleep(self.other_locks_go_away_delay) |
| 192 | logger.debug("LOCK-ACQUIRE: timeout while waiting for non-exclusive locks to go away.") |
| 193 | break # timeout |
| 194 | else: |
| 195 | logger.debug("LOCK-ACQUIRE: someone else also created an exclusive lock, deleting ours.") |
| 196 | self._delete_lock(key, ignore_not_found=True, update_last_refresh=True) |
| 197 | else: # not is_exclusive |
| 198 | if len(exclusive_locks) == 0: |
| 199 | logger.debug("LOCK-ACQUIRE: success! no exclusive locks detected.") |
| 200 | # We don't care for other non-exclusive locks. |
| 201 | return self |
| 202 | else: |
| 203 | logger.debug("LOCK-ACQUIRE: exclusive locks detected, deleting our shared lock.") |
| 204 | self._delete_lock(key, ignore_not_found=True, update_last_refresh=True) |
| 205 | # wait a random bit before retrying |
| 206 | time.sleep( |
| 207 | self.retry_delay_min + (self.retry_delay_max - self.retry_delay_min) * random.random() # nosec B311 |
| 208 | ) |
| 209 | logger.debug("LOCK-ACQUIRE: timeout while trying to acquire a lock.") |
| 210 | raise LockTimeout(str(self.store)) |
| 211 | |
| 212 | def release(self, *, ignore_not_found=False): |
| 213 | self.last_refresh_dt = None |
no test coverage detected