• Get Review Board
  • What's New
  • Products
  • Review Board Code review, image review, and document review
  • Documentation
  • Release Notes
  • Power Pack Enterprise integrations, reports, and enhanced document review
  • Try for 60 Days
  • Purchase
  • RBCommons Review Board as a Service, hosted by us
  • Pricing
  • RBTools Command line tools and Python API for Review Board
  • Documentation
  • Release Notes
  • Review Bot Automated code review, connecting tools you already use
  • Documentation
  • Release Notes
  • RB Gateway Manage Git and Mercurial repositories in your network
  • Documentation
  • Release Notes
  • Learn and Explore
  • What is Code Review?
  • Documentation
  • Frequently Asked Questions
  • Support Options
  • Third-Party Integrations
  • Demo
  • Review Board RBTools Power Pack Review Bot Djblets RB Gateway
    1. Djblets 6.x
    2. Version 6.x
    3. Version 5.x
    4. Version 4.x
    5. Version 3.x
    6. Version 2.x
    7. Version 2.0
    8. Version 1.0
    9. Version 0.9
    10. Djblets Documentation
    11. Module and Class References
    12. djblets.protect.locks
  • Home
  • Guides
  • Avatar Services Guides
  • Writing Avatar Services
  • Caching Guides
  • Caching Data
  • Working with Cache Keys
  • Cache Backends
  • Extension Guides
  • Writing Extensions
  • Testing Extensions
  • Feature Checks Guides
  • Introduction to Feature Checks
  • Writing Features
  • Writing Feature Checkers
  • Testing with Feature Checks
  • Integration Guides
  • Supporting Integrations
  • Writing Integrations
  • Dynamic Page Injections
  • Privacy Compliance Guides
  • Getting and Checking Consent
  • Working with Personally Identifiable Information
  • Service Integrations
  • Protection Guides
  • Rate Limiting Operations
  • reCAPTCHA Guides
  • Using reCAPTCHA
  • Registries Guides
  • Writing Registries
  • Web API Guides
  • Writing Web API Resources
  • Adding OAuth2 Support
  • Module and Class References
  • djblets
  • djblets.deprecation
  • djblets.auth.forms
  • djblets.auth.ratelimit
  • djblets.auth.signals
  • djblets.auth.util
  • djblets.auth.views
  • djblets.avatars.errors
  • djblets.avatars.forms
  • djblets.avatars.registry
  • djblets.avatars.services
  • djblets.avatars.services.base
  • djblets.avatars.services.fallback
  • djblets.avatars.services.file_upload
  • djblets.avatars.services.gravatar
  • djblets.avatars.services.url
  • djblets.avatars.settings
  • djblets.cache
  • djblets.cache.backend
  • djblets.cache.backend_compat
  • djblets.cache.context_processors
  • djblets.cache.errors
  • djblets.cache.forwarding_backend
  • djblets.cache.serials
  • djblets.cache.synchronizer
  • djblets.conditions
  • djblets.conditions.choices
  • djblets.conditions.conditions
  • djblets.conditions.errors
  • djblets.conditions.operators
  • djblets.conditions.values
  • djblets.configforms.forms
  • djblets.configforms.mixins
  • djblets.configforms.pages
  • djblets.configforms.registry
  • djblets.configforms.views
  • djblets.datagrid
  • djblets.datagrid.grids
  • djblets.db.backends.mysql.base
  • djblets.db.fields
  • djblets.db.fields.base64_field
  • djblets.db.fields.comma_separated_values_field
  • djblets.db.fields.counter_field
  • djblets.db.fields.json_field
  • djblets.db.fields.modification_timestamp_field
  • djblets.db.fields.relation_counter_field
  • djblets.db.managers
  • djblets.db.query
  • djblets.db.query_catcher
  • djblets.db.query_comparator
  • djblets.db.validators
  • djblets.pagestate
  • djblets.pagestate.injectors
  • djblets.pagestate.middleware
  • djblets.pagestate.state
  • djblets.pagestate.templatetags.djblets_pagestate
  • djblets.extensions
  • djblets.extensions.admin
  • djblets.extensions.errors
  • djblets.extensions.extension
  • djblets.extensions.forms
  • djblets.extensions.hooks
  • djblets.extensions.loaders
  • djblets.extensions.manager
  • djblets.extensions.middleware
  • djblets.extensions.models
  • djblets.extensions.packaging
  • djblets.extensions.resources
  • djblets.extensions.settings
  • djblets.extensions.signals
  • djblets.extensions.staticfiles
  • djblets.extensions.testing
  • djblets.extensions.testing.testcases
  • djblets.extensions.urls
  • djblets.extensions.views
  • djblets.extensions.templatetags.djblets_extensions
  • djblets.features
  • djblets.features.checkers
  • djblets.features.decorators
  • djblets.features.errors
  • djblets.features.feature
  • djblets.features.level
  • djblets.features.registry
  • djblets.features.testing
  • djblets.features.templatetags.features
  • djblets.forms.fields
  • djblets.forms.fieldsets
  • djblets.forms.forms
  • djblets.forms.forms.key_value_form
  • djblets.forms.widgets
  • djblets.gravatars
  • djblets.gravatars.templatetags.gravatars
  • djblets.http.middleware
  • djblets.http.requests
  • djblets.http.responses
  • djblets.integrations.errors
  • djblets.integrations.forms
  • djblets.integrations.hooks
  • djblets.integrations.integration
  • djblets.integrations.manager
  • djblets.integrations.mixins
  • djblets.integrations.models
  • djblets.integrations.urls
  • djblets.integrations.views
  • djblets.log
  • djblets.log.middleware
  • djblets.log.siteconfig
  • djblets.log.urls
  • djblets.log.views
  • djblets.mail.dmarc
  • djblets.mail.message
  • djblets.mail.testing
  • djblets.mail.utils
  • djblets.markdown
  • djblets.markdown.extensions.escape_html
  • djblets.markdown.extensions.wysiwyg
  • djblets.markdown.extensions.wysiwyg_email
  • djblets.pipeline.compilers.es6
  • djblets.pipeline.compilers.less
  • djblets.pipeline.compilers.mixins
  • djblets.pipeline.compilers.rollup
  • djblets.pipeline.compilers.typescript
  • djblets.pipeline.settings
  • djblets.privacy.consent
  • djblets.privacy.consent.base
  • djblets.privacy.consent.common
  • djblets.privacy.consent.errors
  • djblets.privacy.consent.forms
  • djblets.privacy.consent.hooks
  • djblets.privacy.consent.registry
  • djblets.privacy.consent.tracker
  • djblets.privacy.models
  • djblets.privacy.pii
  • djblets.privacy.templatetags.djblets_privacy
  • djblets.protect
  • djblets.protect.locks
  • djblets.protect.ratelimit
  • djblets.recaptcha.mixins
  • djblets.recaptcha.siteconfig
  • djblets.recaptcha.templatetags.djblets_recaptcha
  • djblets.recaptcha.widgets
  • djblets.registries
  • djblets.registries.errors
  • djblets.registries.importer
  • djblets.registries.mixins
  • djblets.registries.registry
  • djblets.registries.signals
  • djblets.secrets
  • djblets.secrets.crypto
  • djblets.secrets.token_generators
  • djblets.secrets.token_generators.base
  • djblets.secrets.token_generators.legacy_sha1
  • djblets.secrets.token_generators.registry
  • djblets.secrets.token_generators.vendor_checksum
  • djblets.siteconfig
  • djblets.siteconfig.admin
  • djblets.siteconfig.context_processors
  • djblets.siteconfig.django_settings
  • djblets.siteconfig.forms
  • djblets.siteconfig.managers
  • djblets.siteconfig.middleware
  • djblets.siteconfig.models
  • djblets.siteconfig.signals
  • djblets.siteconfig.views
  • djblets.template.caches
  • djblets.template.context
  • djblets.template.loaders.conditional_cached
  • djblets.template.loaders.namespaced_app_dirs
  • djblets.testing.decorators
  • djblets.testing.testcases
  • djblets.testing.testrunners
  • djblets.urls.context_processors
  • djblets.urls.decorators
  • djblets.urls.patterns
  • djblets.urls.resolvers
  • djblets.urls.root
  • djblets.urls.staticfiles
  • djblets.util.compat.django.core.cache
  • djblets.util.compat.python.past
  • djblets.util.contextmanagers
  • djblets.util.dates
  • djblets.util.decorators
  • djblets.util.filesystem
  • djblets.util.functional
  • djblets.util.html
  • djblets.util.http
  • djblets.util.humanize
  • djblets.util.json_utils
  • djblets.util.properties
  • djblets.util.serializers
  • djblets.util.symbols
  • djblets.util.templatetags.djblets_deco
  • djblets.util.templatetags.djblets_email
  • djblets.util.templatetags.djblets_forms
  • djblets.util.templatetags.djblets_images
  • djblets.util.templatetags.djblets_js
  • djblets.util.templatetags.djblets_utils
  • djblets.util.typing
  • djblets.util.views
  • djblets.views.generic.base
  • djblets.views.generic.etag
  • djblets.webapi.auth
  • djblets.webapi.auth.backends
  • djblets.webapi.auth.backends.api_tokens
  • djblets.webapi.auth.backends.base
  • djblets.webapi.auth.backends.basic
  • djblets.webapi.auth.backends.oauth2_tokens
  • djblets.webapi.auth.views
  • djblets.webapi.decorators
  • djblets.webapi.encoders
  • djblets.webapi.errors
  • djblets.webapi.fields
  • djblets.webapi.managers
  • djblets.webapi.models
  • djblets.webapi.oauth2_scopes
  • djblets.webapi.resources
  • djblets.webapi.resources.base
  • djblets.webapi.resources.group
  • djblets.webapi.resources.registry
  • djblets.webapi.resources.root
  • djblets.webapi.resources.user
  • djblets.webapi.resources.mixins.api_tokens
  • djblets.webapi.resources.mixins.forms
  • djblets.webapi.resources.mixins.oauth2_tokens
  • djblets.webapi.resources.mixins.queries
  • djblets.webapi.responses
  • djblets.webapi.signals
  • djblets.webapi.testing
  • djblets.webapi.testing.decorators
  • djblets.webapi.testing.testcases
  • General Index
  • Python Module Index
  • Release Notes
  • djblets.protect.locks¶

    Locking implementations.

    New in version 6.0.

    class CacheLock(key: str | Sequence[str] = '', *, blocking: bool = True, lock_expiration_secs: int = 30, retry_secs: float = 0.25, timeout_secs: float = -1)[source]¶

    Bases: object

    A distributed lock backed by a cache.

    This is used to acquire a lock associated with a key, either blocking or immediately returning if a lock can’t immediately be acquired.

    Locks can be used by code that needs to run only once across multiple processes or servers. They can be used directly or passed to cache_memoize() or cache_memoize_iter() to wrap any cache updates in a lock.

    Locks have an expiration time in order to prevent deadlocks. Setting this higher can result in longer wait periods if the lock fails to be released. Setting it lower can result in locks automatically releasing prematurely. It defaults to an expiration of 30 seconds.

    The interface is kept compatible with threading.Lock, but with additional capabilities for updating expiration times and setting default blocking and timeout behavior during construction.

    Note

    This lock is subject to the limitations of the cache system. The lock may be purged from cache without notice, and it’s possible for one client to overwrite another’s lock depending on timing issues or scaling setup.

    For these reasons, this lock should be considered an imperfect, lossy lock. Callers can use it to help prevent multiple operations from occurring at once, but they should be tolerant of that possibility and designed accordingly.

    CacheLocks are also not thread-safe. Do not reuse the same lock across threads.

    New in version 6.0.

    __init__(key: str | Sequence[str] = '', *, blocking: bool = True, lock_expiration_secs: int = 30, retry_secs: float = 0.25, timeout_secs: float = -1) → None[source]¶

    Initialize the lock.

    Parameters:
    • key (str or list of str) –

      The key to use in the cache.

      This may be a sequence of strings, which will take care of serializing each component to help avoid key injection attacks.

      This will be passed to make_cache_key() to construct a full cache key.

    • blocking (bool, optional) – Whether this lock will block for a period of time to be acquired.

    • lock_expiration_secs (int, optional) –

      The max amount of time a lock can be claimed.

      After this period, the lock will be automatically released.

    • retry_secs (float, optional) –

      The time to sleep between checking for a lock to be released.

      The caller should set this to be less than the timeout, but note that timeouts can be extended or reduced by the lock owner.

      An additional jitter between 0-25% of the retry time will be added to reduce stampede issues.

    • timeout_secs (float, optional) –

      The max time to wait for a lock to be released.

      If -1, the lock will block indefinitely.

    Raises:

    ValueError – A provided argument had an invalid value.

    blocking: bool¶

    Whether this lock will block for a period of time to be acquired.

    retry_secs: float¶

    The time to sleep between checking for a lock to be released.

    timeout_secs: float¶

    The max time to wait for a lock to be released.

    If -1, the lock will wait indefinitely.

    lock_expiration_secs: int¶

    The max amount of time a lock can be claimed.

    acquired: bool¶

    Whether a lock is currently acquired by this instance.

    token: str¶

    The cached token value associated with this lock instance.

    __annotations__ = {'_lock_expires_time': 'float', 'acquired': 'bool', 'blocking': 'bool', 'full_cache_key': 'str', 'lock_expiration_secs': 'int', 'retry_secs': 'float', 'timeout_secs': 'float', 'token': 'str'}¶
    full_cache_key: str¶

    The full cache key used for the lock.

    This may be set lazily after the lock is constructed, but must be set prior to acquiring a lock.

    __del__() → None[source]¶

    Handle destruction of the cache lock.

    If this lock was garbage collected without being released, an exception will be logged indicating an implementation problem with the caller’s use of the lock.

    locked() → bool[source]¶

    Return whether the lock is acquired.

    This wraps acquired, and provides API compatibility with threading.Lock and other Python lock objects.

    Returns:

    True if the lock has been acquired. False if it has not.

    Return type:

    bool

    acquire(blocking: bool | None = None, timeout: float | None = None) → bool[source]¶

    Acquire a lock.

    If there’s already an existing lock in cache, this will either return immediately or wait for the lock to be released, depending on blocking.

    If waiting, this will wait for a total time specified by timeout_secs, checking every retry_secs.

    Waiting uses the monotonic clock, so it’s not affected by changes to the system clock.

    To ensure API compatibility with threading.Lock and other Python lock objects, this method can also take arguments that override the values provided during construction.

    Returns:

    True if the lock could be acquired (even after waiting). False if it could not (only if blocking is False).

    Return type:

    bool

    Raises:
    • RuntimeError – An attempt was made to acquire a lock that was already acquired.

    • TimeoutError – The lock could not be acquired due to the wait time expiring.

    • ValueError – A cache key was never set for the lock.

    update_expiration(lock_expiration_secs: int | None = None) → None[source]¶

    Update the expiration of the lock.

    This can be used to keep the lock opened a bit longer, in case there’s work in progress, or to shorten the lock.

    Parameters:

    lock_expiration_secs (int, optional) –

    A specific number of seconds to set for the new expiration.

    If not provided, the original expiration time in seconds will be used.

    Raises:

    AssertionError – The caller called this without first acquiring a lock.

    release() → None[source]¶

    Release a lock.

    If the lock is still valid, it will be removed from the cache, allowing something else to acquire the lock.

    If a lock is not acquired, this will raise an exception.

    Raises:

    RuntimeError – This was called on a lock that was not acquired.

    __enter__() → Self[source]¶

    Enter the context manager.

    This will acquire the lock, if possible, and pass the result as the context. Once the context manager is exited, the lock will be released.

    This is equivalent to calling acquire().

    Context:

    CacheLock – The cache lock instance.

    Raises:
    • TimeoutError – The lock could not be acquired due to the wait time expiring.

    • ValueError – A cache key was never set for the lock.

    __exit__(*args, **kwargs) → None[source]¶

    Exit the context manager.

    This will release the lock, if one was acquired.

    Parameters:
    • *args (tuple, unused) – Unused positional arguments.

    • **kwargs (dict, unused) – Unused keyword arguments.

    __repr__() → str[source]¶

    Return a string representation of the cache lock object.

    Returns:

    The string representation.

    Return type:

    str

    Keep up with the latest Review Board releases, security updates, and helpful information.

    About
    News
    Demo
    RBCommons Hosting
    Integrations
    Happy Users
    Support Options
    Documentation
    FAQ
    User Manual
    RBTools
    Administration Guide
    Power Pack
    Release Notes
    Downloads
    Review Board
    RBTools
    Djblets
    Power Pack
    Package Store
    PGP Signatures
    Contributing
    Bug Tracker
    Submit Patches
    Development Setup
    Wiki
    Follow Us
    Mailing Lists
    Reddit
    Twitter
    Mastodon
    Facebook
    YouTube

    Copyright © 2006-2026 Beanbag, Inc. All rights reserved.

    Terms of Service — Privacy Policy — AI Ethics Policy — Branding

    On this page

    • [Top]
    • CacheLock
      • CacheLock.__init__()
      • CacheLock.blocking
      • CacheLock.retry_secs
      • CacheLock.timeout_secs
      • CacheLock.lock_expiration_secs
      • CacheLock.acquired
      • CacheLock.token
      • CacheLock.__annotations__
      • CacheLock.full_cache_key
      • CacheLock.__del__()
      • CacheLock.locked()
      • CacheLock.acquire()
      • CacheLock.update_expiration()
      • CacheLock.release()
      • CacheLock.__enter__()
      • CacheLock.__exit__()
      • CacheLock.__repr__()