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
|
@contextmanager
|
||||||
def claim_for_update(resource, minutes=30):
|
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__
|
Model = resource.__class__
|
||||||
|
|
||||||
claim_until = func.now() + func.cast(
|
claim_until = func.now() + func.cast(
|
||||||
sql.functions.concat(minutes, " MINUTES"), Interval
|
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 = (
|
rows_updated = (
|
||||||
db.session.query(Model)
|
db.session.query(Model)
|
||||||
.filter(
|
.filter(
|
||||||
@ -26,11 +36,14 @@ def claim_for_update(resource, minutes=30):
|
|||||||
if rows_updated < 1:
|
if rows_updated < 1:
|
||||||
raise ClaimFailedException(resource)
|
raise ClaimFailedException(resource)
|
||||||
|
|
||||||
|
# Fetch the claimed resource
|
||||||
claimed = db.session.query(Model).filter_by(id=resource.id).one()
|
claimed = db.session.query(Model).filter_by(id=resource.id).one()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Give the resource to the caller.
|
||||||
yield claimed
|
yield claimed
|
||||||
finally:
|
finally:
|
||||||
|
# Release the claim.
|
||||||
db.session.query(Model).filter(Model.id == resource.id).filter(
|
db.session.query(Model).filter(Model.id == resource.id).filter(
|
||||||
Model.claimed_until != None
|
Model.claimed_until != None
|
||||||
).update({"claimed_until": None}, synchronize_session="fetch")
|
).update({"claimed_until": None}, synchronize_session="fetch")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user