🔍 Code Extractor

function unlocked

Maturity: 46

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

File:
/tf/active/vicechatdev/patches/server.py
Lines:
427 - 468
Complexity:
complex

Purpose

This function is used in Panel/Bokeh applications to manage document locking and event dispatching. It ensures that model changes made within the context are properly communicated to all active WebSocket connections while handling document hold/unhold states. This is critical for real-time updates in interactive web applications where multiple clients may be connected to the same session.

Source Code

def unlocked():
    """
    Context manager which unlocks a Document and dispatches
    ModelChangedEvents triggered in the context body to all sockets
    on current sessions.
    """
    curdoc = state.curdoc
    if curdoc is None or curdoc.session_context is None or curdoc.session_context.session is None:
        yield
        return
    connections = curdoc.session_context.session._subscribed_connections

    hold = curdoc.callbacks.hold_value
    if hold:
        old_events = list(curdoc.callbacks._held_events)
    else:
        old_events = []
        curdoc.hold()
    try:
        yield
        events = []
        for conn in connections:
            socket = conn._socket
            if hasattr(socket, 'write_lock') and socket.write_lock._block._value == 0:
                state._locks.add(socket)
            locked = socket in state._locks
            for event in curdoc.callbacks._held_events:
                if (isinstance(event, ModelChangedEvent) and event not in old_events
                    and hasattr(socket, 'write_message') and not locked):
                    msg = conn.protocol.create('PATCH-DOC', [event])
                    WebSocketHandler.write_message(socket, msg.header_json)
                    WebSocketHandler.write_message(socket, msg.metadata_json)
                    WebSocketHandler.write_message(socket, msg.content_json)
                    for header, payload in msg._buffers:
                        WebSocketHandler.write_message(socket, header)
                        WebSocketHandler.write_message(socket, payload, binary=True)
                elif event not in events:
                    events.append(event)
        curdoc.callbacks._held_events = events
    finally:
        if not hold:
            curdoc.unhold()

Return Value

This is a context manager (generator function) that yields control to the calling code. It does not return a meaningful value but manages the document state and event dispatching as side effects. The yield statement allows code to execute within the context, after which cleanup and event dispatching occur.

Dependencies

  • bokeh
  • tornado
  • param

Required Imports

from contextlib import contextmanager
from bokeh.document.events import ModelChangedEvent
from tornado.websocket import WebSocketHandler

Conditional/Optional Imports

These imports are only needed under specific conditions:

from state import state

Condition: Required to access the current document (curdoc) and locks state

Required (conditional)

Usage Example

from contextlib import contextmanager
from panel.io.state import state
from panel.io.server import unlocked

# Within a Panel/Bokeh server application
def modify_document():
    # Make changes to the document that need to be dispatched
    with unlocked():
        # Any model changes here will be sent to all connected clients
        some_panel_object.param.update(value=new_value)
        another_widget.text = 'Updated text'
    # Changes are dispatched after exiting the context

# Typical use in a callback
def on_button_click(event):
    with unlocked():
        # Update multiple components
        text_widget.value = 'Processing...'
        plot.data = new_data
        # All changes sent together to clients

Best Practices

  • Only use this context manager within a Bokeh/Panel server application where a document and session context exist
  • Be aware that this function directly manipulates WebSocket connections and document event queues
  • The function gracefully handles cases where no document or session exists by yielding immediately
  • Events are filtered to only dispatch ModelChangedEvents that occurred within the context and haven't been dispatched before
  • The function respects existing document hold states and restores them after execution
  • Write locks on sockets are checked to prevent sending messages to locked connections
  • This is an advanced function typically used internally by Panel; most users should rely on Panel's automatic event handling

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function set_curdoc 67.9% similar

    A context manager that temporarily sets the current Bokeh document (curdoc) in the application state, ensuring it is properly cleaned up after use.

    From: /tf/active/vicechatdev/patches/server.py
  • function async_execute 62.8% 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 modify_document 61.0% 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
  • function with_lock 56.9% similar

    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.

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

    Initializes a Bokeh document by registering session information and setting up document lifecycle event handlers for Panel applications.

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