🔍 Code Extractor

class StoppableThread

Maturity: 48

A custom thread class that extends threading.Thread with the ability to gracefully stop a Bokeh server running in the thread by stopping its IOLoop.

File:
/tf/active/vicechatdev/patches/server.py
Lines:
760 - 786
Complexity:
moderate

Purpose

StoppableThread provides a mechanism to run Bokeh server instances in separate threads with proper cleanup capabilities. It wraps the standard threading.Thread functionality and adds a stop() method that can gracefully shut down the Bokeh server and its associated Tornado IOLoop. This is particularly useful for managing Bokeh server lifecycles in applications that need to start and stop servers programmatically, such as in testing environments or dynamic server management scenarios.

Source Code

class StoppableThread(threading.Thread):
    """Thread class with a stop() method."""

    def __init__(self, io_loop=None, **kwargs):
        super().__init__(**kwargs)
        self.io_loop = io_loop

    def run(self):
        if hasattr(self, '_target'):
            target, args, kwargs = self._target, self._args, self._kwargs
        else:
            target, args, kwargs = self._Thread__target, self._Thread__args, self._Thread__kwargs
        if not target:
            return
        bokeh_server = None
        try:
            bokeh_server = target(*args, **kwargs)
        finally:
            if isinstance(bokeh_server, Server):
                bokeh_server.stop()
            if hasattr(self, '_target'):
                del self._target, self._args, self._kwargs
            else:
                del self._Thread__target, self._Thread__args, self._Thread__kwargs

    def stop(self):
        self.io_loop.add_callback(self.io_loop.stop)

Parameters

Name Type Default Kind
bases threading.Thread -

Parameter Details

io_loop: A Tornado IOLoop instance that will be used to stop the thread. This should be the same IOLoop that the Bokeh server is running on. If None, the stop() method will fail. This is typically obtained from the Bokeh Server instance.

**kwargs: Additional keyword arguments passed to the parent threading.Thread constructor. Common arguments include 'target' (the callable to run), 'args' (positional arguments for target), 'kwargs' (keyword arguments for target), 'name' (thread name), and 'daemon' (whether thread is a daemon).

Return Value

Instantiation returns a StoppableThread object that is a subclass of threading.Thread. The run() method returns None. The stop() method returns None but triggers the IOLoop to stop asynchronously via a callback.

Class Interface

Methods

__init__(self, io_loop=None, **kwargs)

Purpose: Initialize the StoppableThread with an IOLoop and pass additional arguments to the parent Thread class

Parameters:

  • io_loop: Tornado IOLoop instance for stopping the thread, defaults to None
  • **kwargs: Additional keyword arguments for threading.Thread (target, args, kwargs, name, daemon, etc.)

Returns: None (constructor)

run(self)

Purpose: Override of Thread.run() that executes the target function and ensures proper cleanup of the Bokeh server and internal references

Returns: None, but may return early if no target is set

stop(self)

Purpose: Gracefully stop the thread by stopping the associated IOLoop via a callback

Returns: None, triggers asynchronous IOLoop stop

Attributes

Name Type Description Scope
io_loop tornado.ioloop.IOLoop or None The Tornado IOLoop instance used to stop the thread. Must be set for stop() to work properly. instance
_target callable or None The callable object to be invoked by the run() method (Python 3.10+). Inherited from threading.Thread. instance
_args tuple Positional arguments for the target callable (Python 3.10+). Inherited from threading.Thread. instance
_kwargs dict Keyword arguments for the target callable (Python 3.10+). Inherited from threading.Thread. instance
_Thread__target callable or None The callable object to be invoked by the run() method (Python < 3.10). Name-mangled attribute from threading.Thread. instance
_Thread__args tuple Positional arguments for the target callable (Python < 3.10). Name-mangled attribute from threading.Thread. instance
_Thread__kwargs dict Keyword arguments for the target callable (Python < 3.10). Name-mangled attribute from threading.Thread. instance

Dependencies

  • threading
  • bokeh
  • tornado

Required Imports

import threading
from bokeh.server.server import Server
from tornado.ioloop import IOLoop

Usage Example

from tornado.ioloop import IOLoop
from bokeh.server.server import Server
from bokeh.application import Application

# Define a function that creates and returns a Bokeh server
def create_server():
    app = Application()
    io_loop = IOLoop.current()
    server = Server({'/': app}, io_loop=io_loop, port=5006)
    server.start()
    server.io_loop.start()
    return server

# Create and start the stoppable thread
io_loop = IOLoop()
thread = StoppableThread(io_loop=io_loop, target=create_server)
thread.start()

# Later, stop the thread gracefully
thread.stop()
thread.join()  # Wait for thread to finish

Best Practices

  • Always provide an io_loop parameter during instantiation to enable the stop() method
  • The target function should return a Bokeh Server instance for automatic cleanup
  • Call thread.join() after stop() to ensure the thread has fully terminated before proceeding
  • The thread automatically cleans up internal references to target, args, and kwargs after execution
  • Handle both Python 3.10+ (_target) and older Python versions (_Thread__target) attribute naming
  • The stop() method uses add_callback to ensure thread-safe stopping of the IOLoop
  • If the target function doesn't return a Server instance, manual cleanup may be required
  • Consider setting daemon=True if the thread should not prevent program exit

Similar Components

AI-powered semantic similarity - components with related functionality:

  • function async_execute 44.4% 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
  • class RootHandler 43.5% similar

    A custom Tornado request handler that extends Bokeh's RootHandler to handle root URL requests with authentication and conditional redirection based on index file extensions.

    From: /tf/active/vicechatdev/patches/server.py
  • class Application 41.7% similar

    A custom Bokeh Application subclass that extends BkApplication to integrate with Panel's state management system, handling session creation callbacks and document initialization with templates.

    From: /tf/active/vicechatdev/patches/server.py
  • function run_smtp_server 41.5% similar

    Initializes and runs an asynchronous SMTP server using a new event loop, with proper error handling and graceful shutdown.

    From: /tf/active/vicechatdev/email-forwarder/src/forwarder/smtp_server.py
  • class periodic 40.1% similar

    A threading class that executes a callback function periodically at specified intervals, with optional count limits and timeout controls.

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