Add a docstring and some comments
This commit is contained in:
parent
23261da3af
commit
7004f7d37e
@ -7,12 +7,22 @@ from atst.domain.exceptions import ClaimFailedException
|
||||
|
||||
@contextmanager
|
||||
def claim_for_update(resource, minutes=30):
|
||||
"""
|
||||
Claim a mutually exclusive expiring hold on a resource.
|
||||
Uses the database as a central source of time in case the server clocks have drifted.
|
||||
|
||||
Args:
|
||||
resource: A SQLAlchemy model instance with a `claimed_until` attribute.
|
||||
minutes: The maximum amount of time, in minutes, to hold the claim.
|
||||
"""
|
||||
Model = resource.__class__
|
||||
|
||||
claim_until = func.now() + func.cast(
|
||||
sql.functions.concat(minutes, " MINUTES"), Interval
|
||||
)
|
||||
|
||||
# Optimistically query for and update the resource in question. If it's
|
||||
# already claimed, `rows_updated` will be 0 and we can give up.
|
||||
rows_updated = (
|
||||
db.session.query(Model)
|
||||
.filter(
|
||||
@ -26,11 +36,14 @@ def claim_for_update(resource, minutes=30):
|
||||
if rows_updated < 1:
|
||||
raise ClaimFailedException(resource)
|
||||
|
||||
# Fetch the claimed resource
|
||||
claimed = db.session.query(Model).filter_by(id=resource.id).one()
|
||||
|
||||
try:
|
||||
# Give the resource to the caller.
|
||||
yield claimed
|
||||
finally:
|
||||
# Release the claim.
|
||||
db.session.query(Model).filter(Model.id == resource.id).filter(
|
||||
Model.claimed_until != None
|
||||
).update({"claimed_until": None}, synchronize_session="fetch")
|
||||
|
Loading…
x
Reference in New Issue
Block a user