Skip to content

Instantly share code, notes, and snippets.

@hishnash
Last active March 14, 2017 10:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hishnash/77c6738580656a82e5c39081fbf77dee to your computer and use it in GitHub Desktop.
Save hishnash/77c6738580656a82e5c39081fbf77dee to your computer and use it in GitHub Desktop.
def exclusive_lock(method):
@wraps(method)
def wrapped_method(self, request, *args, document_pk=None, **kwargs):
document = self.assert_user_has_write_permission(document_pk)
document_state = self.get_document_state(document=document)
# currently there is no transaction,
# the context managers will create/release as needed
with document_state.get_exclusive_lock():
# we have exclusive access
try:
# call the method we're wrapping
return method(
self, request, *args,
document_pk=document_pk,
document=document,
document_state=document_state,
**kwargs)
except NodeRepoException:
# there was an error, reload the document and try again
document_reloader = DocumentReloader(document_state)
# start the cleaner
task = document_reloader.run_task()
# the document's reload should be taking a little longer for the next lock
with document_state.get_exclusive_lock(
timeout=settings.PG_LOCKING_TIMEOUT_MS * 5):
# task ran in another thread
# by fetching the result,
# we will raise any exception it had here
task.result()
# we need to get the state again, it might have change?
document_state = DocumentState.objects.get(document=document)
# if there is an error, we raise it back to the client
return method(
self, request, *args,
document=document,
document_state=document_state,
document_pk=document_pk, **kwargs)
return wrapped_method
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment