🔍 Code Extractor

function with_lock

Maturity: 47

A decorator that wraps callback functions (both sync and async) to mark them for execution with a Bokeh document lock, allowing safe modification of Bokeh models.

File:
/tf/active/vicechatdev/patches/server.py
Lines:
399 - 423
Complexity:
simple

Purpose

This decorator is used in Bokeh/Panel applications to ensure that callback functions can safely modify Bokeh models by executing with the appropriate document lock. It preserves the original function's signature and async nature while adding a 'lock' attribute set to True, which signals to the framework that this function requires lock acquisition before execution. This is critical for thread-safe operations in Bokeh server applications where multiple callbacks might attempt to modify the document simultaneously.

Source Code

def with_lock(func):
    """
    Wrap a callback function to execute with a lock allowing the
    function to modify bokeh models directly.

    Arguments
    ---------
    func: callable
      The callable to wrap

    Returns
    -------
    wrapper: callable
      Function wrapped to execute without a Document lock.
    """
    if inspect.iscoroutinefunction(func):
        @wraps(func)
        async def wrapper(*args, **kw):
            return await func(*args, **kw)
    else:
        @wraps(func)
        def wrapper(*args, **kw):
            return func(*args, **kw)
    wrapper.lock = True
    return wrapper

Parameters

Name Type Default Kind
func - - positional_or_keyword

Parameter Details

func: A callable (function or coroutine function) that needs to be wrapped for lock-protected execution. Can be either a synchronous function or an async coroutine function. The function will be wrapped while preserving its original behavior and signature.

Return Value

Returns a wrapper function that has the same signature and behavior as the input function, but with an additional 'lock' attribute set to True. If the input is a coroutine function, returns an async wrapper; otherwise returns a synchronous wrapper. The wrapper preserves the original function's metadata through functools.wraps.

Dependencies

  • inspect
  • functools

Required Imports

import inspect
from functools import wraps

Usage Example

import inspect
from functools import wraps

def with_lock(func):
    if inspect.iscoroutinefunction(func):
        @wraps(func)
        async def wrapper(*args, **kw):
            return await func(*args, **kw)
    else:
        @wraps(func)
        def wrapper(*args, **kw):
            return func(*args, **kw)
    wrapper.lock = True
    return wrapper

# Example 1: Synchronous callback
@with_lock
def update_plot(event):
    # Safely modify Bokeh models
    plot.title.text = 'Updated Title'
    return 'Updated'

# Example 2: Async callback
@with_lock
async def async_update(event):
    # Safely modify Bokeh models in async context
    await some_async_operation()
    plot.title.text = 'Async Updated'
    return 'Done'

# Check that lock attribute is set
print(update_plot.lock)  # True
print(async_update.lock)  # True

Best Practices

  • Use this decorator on any callback function that modifies Bokeh models to ensure thread-safe execution
  • The decorator automatically detects whether the function is async or sync and wraps it appropriately
  • The 'lock' attribute on the wrapper is used by the framework to determine lock acquisition strategy - do not modify it manually
  • This decorator should be applied to callbacks used in Bokeh server applications, particularly when using Panel or custom Bokeh applications
  • The decorator preserves the original function's metadata (name, docstring, etc.) through functools.wraps
  • For async functions, ensure your execution environment supports async/await syntax

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function async_execute 63.3% similar

    Wraps and schedules async function execution in the appropriate event loop context, ensuring proper lock propagation and document context management for Bokeh/Panel applications.

    From: /tf/active/vicechatdev/patches/server.py
  • function unlocked 56.9% similar

    A context manager that temporarily unlocks a Bokeh Document and dispatches ModelChangedEvents to all connected WebSocket clients during the context execution.

    From: /tf/active/vicechatdev/patches/server.py
  • function guard_execution 50.0% similar

    A decorator factory that prevents rapid repeated execution of a function by enforcing a cooldown period between calls.

    From: /tf/active/vicechatdev/CDocs/__init__.py
  • function run_with_timeout 49.9% similar

    Executes a function with a specified timeout using threading, raising a TimeoutException if the function exceeds the time limit.

    From: /tf/active/vicechatdev/docchat/document_indexer.py
  • function modify_document 45.7% similar

    Modifies a Bokeh document by executing a Python script/module within the document's context, with support for autoreload functionality and error handling.

    From: /tf/active/vicechatdev/patches/server.py
← Back to Browse