This commit is contained in:
Raphaël MANSUY 2025-12-04 19:18:40 +08:00
parent 7fa4f883a6
commit 3f309105b0
8 changed files with 35 additions and 56 deletions

View file

@ -1,4 +0,0 @@
#!/bin/bash
source /home/netman/lightrag-xyj/venv/bin/activate
lightrag-server

View file

@ -9,14 +9,11 @@ User=netman
MemoryHigh=8G MemoryHigh=8G
MemoryMax=12G MemoryMax=12G
# Set the LightRAG installation directory (change this to match your installation path) # Using virtual enviroment created by miniconda
Environment="LIGHTRAG_HOME=/home/netman/lightrag-xyj" Environment="PATH=/home/netman/miniconda3/bin:/home/netman/lightrag-xyj/venv/bin"
WorkingDirectory=/home/netman/lightrag-xyj
# Set Environment to your Python virtual environment # ExecStart=/home/netman/lightrag-xyj/venv/bin/lightrag-server
Environment="PATH=${LIGHTRAG_HOME}/.venv/bin" ExecStart=/home/netman/lightrag-xyj/venv/bin/lightrag-gunicorn
WorkingDirectory=${LIGHTRAG_HOME}
ExecStart=${LIGHTRAG_HOME}/.venv/bin/lightrag-server
# ExecStart=${LIGHTRAG_HOME}/.venv/bin/lightrag-gunicorn
# Kill mode require ExecStart must be gunicorn or unvicorn main process # Kill mode require ExecStart must be gunicorn or unvicorn main process
KillMode=process KillMode=process

View file

@ -210,24 +210,16 @@ MAX_ASYNC=4
### 将 Lightrag 安装为 Linux 服务 ### 将 Lightrag 安装为 Linux 服务
从示例文件 `lightrag.service.example` 创建您的服务文件 `lightrag.service`。修改服务文件中的 WorkingDirectory 和 ExecStart 从示例文件 `lightrag.service.example` 创建您的服务文件 `lightrag.service`。修改服务文件中的服务启动定义
```text ```text
Description=LightRAG Ollama Service # Set Enviroment to your Python virtual enviroment
WorkingDirectory=<lightrag 安装目录> Environment="PATH=/home/netman/lightrag-xyj/venv/bin"
ExecStart=<lightrag 安装目录>/lightrag/api/lightrag-api WorkingDirectory=/home/netman/lightrag-xyj
``` # ExecStart=/home/netman/lightrag-xyj/venv/bin/lightrag-server
ExecStart=/home/netman/lightrag-xyj/venv/bin/lightrag-gunicorn
修改您的服务启动脚本:`lightrag-api`。根据需要更改 python 虚拟环境激活命令:
```shell
#!/bin/bash
# 您的 python 虚拟环境激活命令
source /home/netman/lightrag-xyj/venv/bin/activate
# 启动 lightrag api 服务器
lightrag-server
``` ```
> ExecStart命令必须是 lightrag-gunicorn 或 lightrag-server 中的一个,不能使用其它脚本包裹它们。因为停止服务必须要求主进程必须是这两个进程。
安装 LightRAG 服务。如果您的系统是 Ubuntu以下命令将生效 安装 LightRAG 服务。如果您的系统是 Ubuntu以下命令将生效

View file

@ -212,24 +212,18 @@ MAX_ASYNC=4
### Install LightRAG as a Linux Service ### Install LightRAG as a Linux Service
Create your service file `lightrag.service` from the sample file: `lightrag.service.example`. Modify the `WorkingDirectory` and `ExecStart` in the service file: Create your service file `lightrag.service` from the sample file: `lightrag.service.example`. Modify the start options the service file:
```text ```text
Description=LightRAG Ollama Service # Set Enviroment to your Python virtual enviroment
WorkingDirectory=<lightrag installed directory> Environment="PATH=/home/netman/lightrag-xyj/venv/bin"
ExecStart=<lightrag installed directory>/lightrag/api/lightrag-api WorkingDirectory=/home/netman/lightrag-xyj
# ExecStart=/home/netman/lightrag-xyj/venv/bin/lightrag-server
ExecStart=/home/netman/lightrag-xyj/venv/bin/lightrag-gunicorn
``` ```
Modify your service startup script: `lightrag-api`. Change your Python virtual environment activation command as needed: > The ExecStart command must be either `lightrag-gunicorn` or `lightrag-server`; no wrapper scripts are allowed. This is because service termination requires the main process to be one of these two executables.
```shell
#!/bin/bash
# your python virtual environment activation
source /home/netman/lightrag-xyj/venv/bin/activate
# start lightrag api server
lightrag-server
```
Install LightRAG service. If your system is Ubuntu, the following commands will work: Install LightRAG service. If your system is Ubuntu, the following commands will work:

View file

@ -133,6 +133,9 @@ def on_exit(server):
print("Finalizing shared storage...") print("Finalizing shared storage...")
finalize_share_data() finalize_share_data()
print("Gunicorn shutdown complete")
print("=" * 80)
print("=" * 80) print("=" * 80)
print("=" * 80) print("=" * 80)

View file

@ -326,12 +326,15 @@ def create_app(args):
# Clean up database connections # Clean up database connections
await rag.finalize_storages() await rag.finalize_storages()
# In Gunicorn mode with preload_app=True, cleanup is handled by worker_exit/on_exit hooks if "LIGHTRAG_GUNICORN_MODE" not in os.environ:
# Only perform cleanup in Uvicorn single-process mode # Only perform cleanup in Uvicorn single-process mode
if "GUNICORN_CMD_ARGS" not in os.environ: logger.debug("Unvicorn Mode: finalizing shared storage...")
# Clean up shared data
finalize_share_data() finalize_share_data()
else:
# In Gunicorn mode with preload_app=True, cleanup is handled by on_exit hooks
logger.debug(
"Gunicorn Mode: postpone shared storage finalization to master process"
)
# Initialize FastAPI # Initialize FastAPI
base_description = ( base_description = (

View file

@ -45,9 +45,7 @@ def main():
check_and_install_dependencies() check_and_install_dependencies()
# Note: Signal handlers are NOT registered here because: # Note: Signal handlers are NOT registered here because:
# - Worker cleanup is handled by gunicorn_config.worker_exit() # - Master cleanup already handled by gunicorn_config.on_exit()
# - Master cleanup is handled by gunicorn_config.on_exit()
# This prevents race conditions when multiple processes try to finalize shared data
# Display startup information # Display startup information
display_splash_screen(global_args) display_splash_screen(global_args)

View file

@ -1565,7 +1565,7 @@ def get_namespace_lock(
return NamespaceLock(namespace, workspace, enable_logging) return NamespaceLock(namespace, workspace, enable_logging)
def finalize_share_data(shutdown_manager: bool = True): def finalize_share_data():
""" """
Release shared resources and clean up. Release shared resources and clean up.
@ -1574,10 +1574,6 @@ def finalize_share_data(shutdown_manager: bool = True):
In multi-process mode, it shuts down the Manager and releases all shared objects. In multi-process mode, it shuts down the Manager and releases all shared objects.
In single-process mode, it simply resets the global variables. In single-process mode, it simply resets the global variables.
Args:
shutdown_manager: If True, shut down the multiprocessing Manager.
Should be True only for the main process, False for worker processes.
""" """
global \ global \
_manager, \ _manager, \
@ -1602,8 +1598,8 @@ def finalize_share_data(shutdown_manager: bool = True):
f"Process {os.getpid()} finalizing storage data (multiprocess={_is_multiprocess})" f"Process {os.getpid()} finalizing storage data (multiprocess={_is_multiprocess})"
) )
# In multi-process mode, shut down the Manager only if requested # In multi-process mode, shut down the Manager
if _is_multiprocess and _manager is not None and shutdown_manager: if _is_multiprocess and _manager is not None:
try: try:
# Clear shared resources before shutting down Manager # Clear shared resources before shutting down Manager
if _shared_dicts is not None: if _shared_dicts is not None: