chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:24:33 +08:00
commit f213ec8976
2101 changed files with 494002 additions and 0 deletions
@@ -0,0 +1,355 @@
.. _common_apis:
Common APIs
===========
.. warning::
This page documents the behavior of LMCache's in-process mode (deprecated). Please consider using :doc:`LMCache MP mode </mp/index>` for better feature support and performance. For the MP mode equivalent of this page, see :doc:`/mp/http_api`.
Common APIs are available across all components (scheduler, worker, controller).
.. contents:: Endpoints
:local:
:depth: 2
``GET /env`` — Environment Variables
-------------------------------------
Get all environment variables of the running process.
- **Method**: ``GET``
- **Path**: ``/env``
- **Parameters**: None
- **Response**: ``application/json`` — JSON object of all environment variables (sorted by key).
.. code-block:: bash
curl http://localhost:7000/env
**Example Response**:
.. code-block:: json
{
"HOME": "/root",
"PATH": "/usr/local/bin:/usr/bin",
"PYTHONPATH": "/app"
}
``GET /loglevel`` — Log Level Management
------------------------------------------
Get or set the log level for Python loggers. Behavior depends on query parameters:
- **No parameters**: List all loggers and their levels.
- **``logger_name`` only**: Get the level of the specified logger.
- **``logger_name`` and ``level``**: Set the level of the specified logger (including all its handlers).
- **Method**: ``GET``
- **Path**: ``/loglevel``
- **Parameters**:
=============== ======== ============================================
Name Type Description
=============== ======== ============================================
``logger_name`` str (Optional) Logger name to query or set
``level`` str (Optional) Log level to set (e.g. ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR``)
=============== ======== ============================================
- **Response**: ``text/plain``
.. code-block:: bash
# List all loggers
curl http://localhost:7000/loglevel
# Get a specific logger level
curl "http://localhost:7000/loglevel?logger_name=lmcache.v1.cache_engine"
# Set a specific logger level
curl "http://localhost:7000/loglevel?logger_name=lmcache.v1.cache_engine&level=DEBUG"
**Example Response** (list all):
.. code-block:: text
=== Loggers and Levels ===
lmcache.v1.cache_engine: WARNING
lmcache.v1.storage_backend: INFO
**Example Response** (get):
.. code-block:: text
lmcache.v1.cache_engine: WARNING
**Example Response** (set):
.. code-block:: text
Set lmcache.v1.cache_engine level to DEBUG (including all handlers)
**Error Response** (invalid level, HTTP 400):
.. code-block:: text
Invalid log level: INVALID_LEVEL
``GET /metrics`` — Prometheus Metrics
--------------------------------------
Get Prometheus metrics data in the standard exposition format.
- **Method**: ``GET``
- **Path**: ``/metrics``
- **Parameters**: None
- **Response**: ``text/plain`` — Prometheus text-based exposition format.
.. code-block:: bash
curl http://localhost:7000/metrics
``POST /metrics/reset`` — Reset Prometheus Metrics
----------------------------------------------------
Reset all Prometheus metrics to their initial state.
- **Method**: ``POST``
- **Path**: ``/metrics/reset``
- **Parameters**: None
- **Response**: ``text/plain````"ok"`` on success.
.. code-block:: bash
curl -X POST http://localhost:7000/metrics/reset
``GET /threads`` — Thread Information
--------------------------------------
Get information about active threads with optional filtering.
- **Method**: ``GET``
- **Path**: ``/threads``
- **Parameters**:
============== ======= ===========================================
Name Type Description
============== ======= ===========================================
``name`` str (Optional) Filter by thread name (fuzzy match, case-insensitive)
``thread_id`` int (Optional) Filter by thread ID
============== ======= ===========================================
- **Response**: ``text/plain`` — Thread info with stack traces and summary.
.. code-block:: bash
# Get all threads
curl http://localhost:7000/threads
# Filter by name
curl "http://localhost:7000/threads?name=api-server"
# Filter by thread ID
curl "http://localhost:7000/threads?thread_id=12345"
``GET /periodic-threads`` — Periodic Thread Status
----------------------------------------------------
Get information about registered periodic threads.
- **Method**: ``GET``
- **Path**: ``/periodic-threads``
- **Parameters**:
================ ======= =============================================
Name Type Description
================ ======= =============================================
``level`` str (Optional) Filter by thread level: ``critical``, ``high``, ``medium``, ``low``
``running_only`` bool (Optional) Only show running threads (default: ``false``)
``active_only`` bool (Optional) Only show active threads (default: ``false``)
================ ======= =============================================
- **Response**: ``application/json``
.. code-block:: bash
# Get all periodic threads
curl http://localhost:7000/periodic-threads
# Filter by level
curl "http://localhost:7000/periodic-threads?level=critical"
# Only running threads
curl "http://localhost:7000/periodic-threads?running_only=true"
**Example Response**:
.. code-block:: json
{
"summary": {
"total_count": 5,
"running_count": 3,
"active_count": 3,
"by_level": {
"critical": {"total": 1, "running": 1, "active": 1},
"high": {"total": 2, "running": 1, "active": 1}
}
},
"threads": [
{
"name": "heartbeat",
"level": "critical",
"is_running": true,
"is_active": true,
"last_run_time": "2025-01-01T00:00:00",
"interval": 10.0
}
]
}
**Error Response** (invalid level, HTTP 400):
.. code-block:: json
{
"error": "Invalid level: unknown. Valid values: critical, high, medium, low"
}
``GET /periodic-threads/{thread_name}`` — Single Periodic Thread
------------------------------------------------------------------
Get detailed information about a specific periodic thread by name.
- **Method**: ``GET``
- **Path**: ``/periodic-threads/{thread_name}``
- **Path Parameters**:
================ ======= =============================================
Name Type Description
================ ======= =============================================
``thread_name`` str Name of the periodic thread
================ ======= =============================================
- **Response**: ``application/json``
.. code-block:: bash
curl http://localhost:7000/periodic-threads/heartbeat
**Error Response** (not found, HTTP 404):
.. code-block:: json
{
"error": "Thread not found: heartbeat"
}
``GET /periodic-threads-health`` — Periodic Thread Health Check
-----------------------------------------------------------------
Quick health check for periodic threads. Returns healthy status if all
``critical`` and ``high`` level threads are active.
- **Method**: ``GET``
- **Path**: ``/periodic-threads-health``
- **Parameters**: None
- **Response**: ``application/json``
.. code-block:: bash
curl http://localhost:7000/periodic-threads-health
**Example Response** (healthy):
.. code-block:: json
{
"healthy": true,
"unhealthy_count": 0,
"unhealthy_threads": []
}
**Example Response** (unhealthy):
.. code-block:: json
{
"healthy": false,
"unhealthy_count": 1,
"unhealthy_threads": [
{
"name": "heartbeat",
"level": "critical",
"last_run_ago": 120.5,
"interval": 10.0
}
]
}
``POST /run_script`` — Run Script
-----------------------------------
Upload and execute a Python script in a restricted sandbox environment.
The script has access to ``app`` (the FastAPI application instance) and
a limited set of builtins. Import is restricted to modules configured
in ``script_allowed_imports``.
- **Method**: ``POST``
- **Path**: ``/run_script``
- **Content-Type**: ``multipart/form-data``
- **Parameters**:
============ ======== =============================================
Name Type Description
============ ======== =============================================
``script`` file Python script file to execute
============ ======== =============================================
- **Response**: ``text/plain`` — The ``result`` variable from the script, or
``"Script executed successfully"`` if no ``result`` is set.
.. code-block:: bash
curl -X POST http://localhost:7000/run_script \
-F "script=@/path/to/scratch.py"
**Example Script** (``scratch.py``):
.. code-block:: python
lmcache_engine = app.state.lmcache_adapter.lmcache_engine
result = {
"is_first_rank": lmcache_engine.metadata.is_first_rank(),
"model_version": lmcache_engine.metadata.kv_shape,
}
**Example Response**:
.. code-block:: text
{'is_first_rank': True, 'model_version': (27, 1, 64, 1, 576)}
**Error Response** (no script, HTTP 400):
.. code-block:: text
No script file provided
**Error Response** (execution error, HTTP 500):
.. code-block:: text
Error executing script: Import of 'os' is not allowed
@@ -0,0 +1,201 @@
.. _controller_apis:
Controller APIs
===============
.. warning::
This page documents the behavior of LMCache's in-process mode (deprecated). Please consider using :doc:`LMCache MP mode </mp/index>` for better feature support and performance. For the MP mode equivalent of this page, see :doc:`/mp/http_api`.
These APIs are specific to the LMCache Controller component. They provide
visibility into registered instances, workers, and key statistics.
.. contents:: Endpoints
:local:
:depth: 2
``GET /controller/key-stats`` — Key Statistics
------------------------------------------------
Get key statistics across all instances and workers.
- **Method**: ``GET``
- **Path**: ``/controller/key-stats``
- **Parameters**: None
- **Response**: ``application/json``
.. code-block:: bash
curl http://localhost:6999/controller/key-stats
**Example Response** (HTTP 200):
.. code-block:: json
{
"total_key_count": 1500,
"total_instance_count": 2,
"total_worker_count": 4,
"instances": [
{
"instance_id": "instance_001",
"key_count": 800,
"worker_count": 2
},
{
"instance_id": "instance_002",
"key_count": 700,
"worker_count": 2
}
]
}
**Error Response** (controller not available, HTTP 503):
.. code-block:: json
{
"detail": "Controller manager not available"
}
**Response Schema**:
========================= ======= =============================================
Field Type Description
========================= ======= =============================================
``total_key_count`` int Total number of KV keys across all instances
``total_instance_count`` int Total number of registered instances
``total_worker_count`` int Total number of workers across all instances
``instances`` list Per-instance breakdown (see below)
========================= ======= =============================================
**Instance Schema**:
================= ======= =============================================
Field Type Description
================= ======= =============================================
``instance_id`` str Unique identifier of the instance
``key_count`` int Number of KV keys held by this instance
``worker_count`` int Number of workers in this instance
================= ======= =============================================
``GET /controller/workers`` — Worker Information
--------------------------------------------------
Get worker information with flexible query parameters. Behavior depends
on the combination of parameters:
- **No parameters**: List all registered workers across all instances.
- **``instance_id`` only**: List all workers for a specific instance.
- **``instance_id`` and ``worker_id``**: Get detailed info about a specific worker.
- **Method**: ``GET``
- **Path**: ``/controller/workers``
- **Parameters**:
================ ======= =============================================
Name Type Description
================ ======= =============================================
``instance_id`` str (Optional) Instance ID to filter workers
``worker_id`` int (Optional) Worker ID for specific worker details (requires ``instance_id``)
================ ======= =============================================
- **Response**: ``application/json``
.. code-block:: bash
# List all workers
curl http://localhost:6999/controller/workers
# List workers for a specific instance
curl "http://localhost:6999/controller/workers?instance_id=instance_001"
# Get a specific worker
curl "http://localhost:6999/controller/workers?instance_id=instance_001&worker_id=0"
**Example Response** (list workers):
.. code-block:: json
{
"workers": [
{
"instance_id": "instance_001",
"worker_id": 0,
"ip": "10.0.0.1",
"port": 8000,
"peer_init_url": "http://10.0.0.1:8000/init",
"registration_time": 1706745600.0,
"last_heartbeat_time": 1706745660.0,
"key_count": 400
},
{
"instance_id": "instance_001",
"worker_id": 1,
"ip": "10.0.0.2",
"port": 8001,
"peer_init_url": "http://10.0.0.2:8001/init",
"registration_time": 1706745600.0,
"last_heartbeat_time": 1706745660.0,
"key_count": 400
}
],
"total_count": 2
}
**Example Response** (single worker):
.. code-block:: json
{
"instance_id": "instance_001",
"worker_id": 0,
"ip": "10.0.0.1",
"port": 8000,
"peer_init_url": "http://10.0.0.1:8000/init",
"registration_time": 1706745600.0,
"last_heartbeat_time": 1706745660.0,
"key_count": 400
}
**Error Response** (worker not found, HTTP 404):
.. code-block:: json
{
"detail": "Worker (instance_001, 99) not found"
}
**Error Response** (instance not found, HTTP 404):
.. code-block:: json
{
"detail": "No workers found for instance unknown_instance"
}
**Error Response** (controller not available, HTTP 503):
.. code-block:: json
{
"detail": "Controller manager not available"
}
**Worker Response Schema**:
========================== ======= =============================================
Field Type Description
========================== ======= =============================================
``instance_id`` str Instance this worker belongs to
``worker_id`` int Worker index within the instance
``ip`` str Worker IP address
``port`` int Worker port number
``peer_init_url`` str (Optional) Peer initialization URL
``registration_time`` float Unix timestamp of worker registration
``last_heartbeat_time`` float Unix timestamp of last heartbeat
``key_count`` int Number of KV keys held by this worker
========================== ======= =============================================
@@ -0,0 +1,181 @@
.. _dynamic_backend_management:
Dynamic Backend Management
==========================
.. warning::
This page documents the behavior of LMCache's in-process mode (deprecated). Please consider using :doc:`LMCache MP mode </mp/index>` for better feature support and performance. For the MP mode equivalent of this page, see :doc:`/mp/http_api`.
LMCache provides a set of internal API endpoints that allow you to **list**,
**close**, and **create** storage backends at runtime without restarting the
serving engine. This is useful when you need to switch between different
storage configurations on the fly — for example, migrating from a
``LocalDiskBackend`` to a ``GdsBackend``, or changing the remote connector
from a filesystem connector to Redis.
Overview
--------
The workflow for dynamically switching a storage backend is:
1. **Close** the backend you want to replace.
2. **Update** the relevant configuration via the ``POST /conf`` API.
3. **Create** new backends — only backends that are not already present
will be created.
Any backend that was **not** closed will be skipped during creation,
so the operation is safe and idempotent.
API Endpoints
-------------
``GET /backends``
^^^^^^^^^^^^^^^^^
List all active storage backends.
.. code-block:: bash
curl http://localhost:7000/backends
Response:
.. code-block:: json
{
"LocalCPUBackend": "LocalCPUBackend",
"RemoteBackend": "RemoteBackend"
}
``DELETE /backends/{backend_name}``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Close and remove a specific storage backend. After this call the backend
is fully shut down and removed from the internal dictionary, ensuring no
stale references remain.
.. code-block:: bash
curl -X DELETE http://localhost:7000/backends/RemoteBackend
Response:
.. code-block:: json
{
"status": "success",
"message": "Backend RemoteBackend closed",
"backends": {
"LocalCPUBackend": "LocalCPUBackend"
}
}
``POST /backends``
^^^^^^^^^^^^^^^^^^
Create new storage backends based on the current ``LMCacheEngineConfig``.
Existing backends are skipped.
.. code-block:: bash
curl -X POST http://localhost:7000/backends
Response:
.. code-block:: json
{
"status": "success",
"created": {
"RemoteBackend": "RemoteBackend"
},
"backends": {
"LocalCPUBackend": "LocalCPUBackend",
"RemoteBackend": "RemoteBackend"
}
}
Use-Case Examples
-----------------
Switching from ``LocalDiskBackend`` to ``GdsBackend``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you originally configured a local-disk backend and want to migrate to
NVIDIA GPUDirect Storage (GDS) at runtime:
.. code-block:: bash
# 1. Close the old disk backend
curl -X DELETE http://localhost:7000/backends/LocalDiskBackend
# 2. Disable local_disk and set the GDS path
curl -X POST http://localhost:7000/conf \
-H "Content-Type: application/json" \
-d '{
"local_disk": false,
"gds_path": "/mnt/nvme/lmcache_gds"
}'
# 3. Create the new GDS backend
curl -X POST http://localhost:7000/backends
# 4. Verify the new backend list
curl http://localhost:7000/backends
Switching ``RemoteBackend`` connector (FS → Redis)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To change the remote connector type without restarting:
.. code-block:: bash
# 1. Close the old remote backend
curl -X DELETE http://localhost:7000/backends/RemoteBackend
# 2. Update the remote URL to point to Redis
curl -X POST http://localhost:7000/conf \
-H "Content-Type: application/json" \
-d '{
"remote_url": "redis://redis-host:6379"
}'
# 3. Create the new remote backend with Redis connector
curl -X POST http://localhost:7000/backends
# 4. Verify
curl http://localhost:7000/backends
Replacing only one backend while keeping others
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If only the ``RemoteBackend`` needs to be updated but the
``LocalCPUBackend`` should stay untouched:
.. code-block:: bash
# Close only the remote backend
curl -X DELETE http://localhost:7000/backends/RemoteBackend
# Update config
curl -X POST http://localhost:7000/conf \
-H "Content-Type: application/json" \
-d '{"remote_url": "redis://new-redis:6379"}'
# Create — LocalCPUBackend is skipped (already present)
curl -X POST http://localhost:7000/backends
Notes
-----
- Closing the ``LocalCPUBackend`` is possible but should be done with
caution since many other backends rely on it as an intermediate buffer.
- The ``POST /backends`` endpoint calls the same ``CreateStorageBackends``
factory that is used during engine initialization, so all backend types
(local CPU, local disk, GDS, remote, P2P, plugins, etc.) are
supported.
- After creating backends, the ``StorageManager`` automatically refreshes
its internal references (``non_allocator_backends``,
``local_cpu_backend``, etc.).
@@ -0,0 +1,85 @@
.. _internal_api_server:
Internal API Server
===================
.. warning::
This page documents the behavior of LMCache's in-process mode (deprecated). Please consider using :doc:`LMCache MP mode </mp/index>` for better feature support and performance. For the MP mode equivalent of this page, see :doc:`/mp/http_api`.
The ``internal_api_server`` provides HTTP APIs for managing and inspecting
the LMCache engine at runtime. APIs are organized into three categories:
- **Common APIs** — Available across all components (scheduler, worker, controller).
- **vLLM / Inference APIs** — Specific to vLLM inference workers.
- **Controller APIs** — Specific to the LMCache Controller.
.. toctree::
:maxdepth: 2
common_apis
vllm_apis
controller_apis
Configuration
-------------
The following parameters can be configured in the YAML file:
.. code-block:: yaml
# Enable/disable the internal API server
internal_api_server_enabled: True
# Base port for the API server
# actual_port = internal_api_server_port_start + index
# Scheduler → 6999 + 0 = 6999
# Worker 0 → 6999 + 1 = 7000
internal_api_server_port_start: 6999
# List of scheduler/worker indices: 0 for scheduler, 1 for worker 0, 2 for worker 1, etc.
internal_api_server_include_index_list: [0, 1]
# Socket path prefix for the API server. If configured, the server will use a Unix socket instead of listening on a port.
internal_api_server_socket_path_prefix: "/tmp/lmcache_internal_api_server/socket"
# Actual socket files will be:
# /tmp/lmcache_internal_api_server/socket_6999 (scheduler)
# /tmp/lmcache_internal_api_server/socket_7000 (worker 0)
Port Assignment
^^^^^^^^^^^^^^^
The port for each component is computed as:
.. code-block:: text
actual_port = internal_api_server_port_start + port_offset
Where ``port_offset`` is:
- ``0`` for the Scheduler
- ``1 + worker_id`` for Workers (e.g., Worker 0 → offset 1, Worker 1 → offset 2)
API Category & Route Discovery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The server uses ``APIRegistry`` to automatically discover and register
API endpoint modules. Any file named ``*_api.py`` under
``lmcache/v1/internal_api_server/{common,vllm,controller}/`` that
exports a ``router = APIRouter()`` will be automatically included.
Extending the Server
^^^^^^^^^^^^^^^^^^^^^
To add a new API endpoint:
1. Create a new file in the appropriate category directory
(``common/``, ``vllm/``, or ``controller/``).
2. Name the file with ``_api.py`` suffix (e.g., ``my_feature_api.py``).
3. Define ``router = APIRouter()`` and add your endpoints.
The endpoint will be automatically discovered and registered on the
next server startup.
File diff suppressed because it is too large Load Diff