Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@shevron
Last active April 3, 2019 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shevron/316eee5e8024dc5f488b27ba5a027553 to your computer and use it in GitHub Desktop.
Save shevron/316eee5e8024dc5f488b27ba5a027553 to your computer and use it in GitHub Desktop.
Examples: MySQL named locks and Python context managers
"""same logic as in above, but using a locking context manager
"""
from app_services import db_session
from locking_context import named_lock
def single_running_func():
"""this code should never execute in parallel
"""
with named_lock(db_session, 'my_lock', 5):
# Do some stuff that should not run in parallel
pass # <-- here for syntax correctness
from app_services import db_session
def single_running_func():
"""this code should never execute in parallel
"""
lock = db_session.execute("SELECT GET_LOCK('my_lock', 5)").scalar()
if not lock:
raise RuntimeError("Could not obtain lock for 5 seconds")
# Do some stuff that should not run in parallel
db_session.execute("SELECT RELEASE_LOCK('my_lock')")
"""locking_context - locking related context managers
"""
import contextlib
@contextlib.contextmanager
def named_lock(db_session, name, timeout):
"""Get a named mysql lock on a DB session
"""
lock = db_session.execute("SELECT GET_LOCK(:lock_name, :timeout)",
{"lock_name": name, "timeout": timeout}).scalar()
if lock:
try:
yield db_session
finally:
db_session.execute("SELECT RELEASE_LOCK(:name)", {"name": name})
else:
e = "Could not obtain named lock {} within {} seconds".format(
name, timeout)
raise RuntimeError(e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment