From 4cbf0ed576ac871fcc58465957478420f8daa1bf Mon Sep 17 00:00:00 2001 From: Darren <27513732@qq.com> Date: Thu, 20 Jul 2023 17:51:24 +0800 Subject: [PATCH] docs --- README.md | 10 +- appmanage/README.md | 8 +- appmanage/docs/API-design.md | 289 ++++++++++++++++++++++++++++++ appmanage/docs/administrator.md | 22 --- appmanage/docs/architecture.md | 83 +++++++-- appmanage/docs/developer.md | 290 ++----------------------------- appmanage/docs/guide.md | 9 - appmanage/docs/images/rq.png | Bin 0 -> 7137 bytes appmanage/test/README.md | 3 + docs/developer.md | 69 -------- docs/{ => notes}/research.md | 0 docs/{ => notes}/软件工厂.md | 0 tests/README.md | 0 13 files changed, 375 insertions(+), 408 deletions(-) create mode 100644 appmanage/docs/API-design.md delete mode 100644 appmanage/docs/administrator.md delete mode 100644 appmanage/docs/guide.md create mode 100644 appmanage/docs/images/rq.png create mode 100644 appmanage/test/README.md rename docs/{ => notes}/research.md (100%) rename docs/{ => notes}/软件工厂.md (100%) delete mode 100644 tests/README.md diff --git a/README.md b/README.md index 5445761f..6f304a77 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ # What is Websoft9? -Websoft9 is web-based PaaS for running 200+ hot [open source application](https://github.com/Websoft9/docker-library/tree/main/apps) on your own server. +Websoft9 is web-based PaaS platform for running 200+ hot [open source application](https://github.com/Websoft9/docker-library/tree/main/apps) on your own server. Websoft9 help you running multiple applications in a single server, that means we believe Microservices on single machine is reasonable. On the contrary, it becomes more and more valuable as computing power increases @@ -44,18 +44,14 @@ You should have root privileges user to install or upgrade Websoft9, if you use wget https://websoft9.github.io/websoft9/install/install.sh && bash install.sh ``` +When installation completed, you can access it by: **http://Internet IP:9000** and using **Linux user** for login + ## Upgrade ``` curl https://websoft9.github.io/websoft9/install/update.sh | bash ``` -## Getting Started - -Using local Chrome or Firefox to visit the URL http://domain:9000 name or http://Internet IP:9000, you will enter the websoft9 - -> Login using the username and password of the Linux operating system - # Contributing Follow the [contributing guidelines](CONTRIBUTING.md) if you want to propose a change in the Websoft9 core. For more information about participating in the community and contributing to the Websoft9 project, see [this page](https://support.websoft9.com/docs/community/contributing). diff --git a/appmanage/README.md b/appmanage/README.md index 031009ec..47793165 100644 --- a/appmanage/README.md +++ b/appmanage/README.md @@ -1,4 +1,8 @@ -# 概述 +# AppManage -appmange 是软件商店的一个重要微服务,管理商店App的安装、卸载、启动、停止以及查询功能。 +AppManage is the core of Websoft9 which can manage application: Create, Stop, Uninstall, Listing + +* [API-design](docs/API-design.md) +* [Architecture](docs/architecture.md) +* [Developer](docs/developer.md) diff --git a/appmanage/docs/API-design.md b/appmanage/docs/API-design.md new file mode 100644 index 00000000..7df23080 --- /dev/null +++ b/appmanage/docs/API-design.md @@ -0,0 +1,289 @@ +# API Design + +## API 结构 + +### 请求 + +#### 请求方式 + +支持如下两种调用方式: + +- get +- post + +#### 请求头(公共参数) + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | ------------ | ------ | ------ | +| Version | 接口版本 | string | 可选 | +| Language | 接口显示语言 | string | 可选 | + +#### 安全验证 + +本微服务没有安全验证模块,需通过 API 网关实现 + +#### 请求主体 + +[业务接口详情](#业务接口详情) + +### 响应结果 + +#### 响应头(公共参数) + +| 返回参数 | 用途 | 类型 | 必要性 | +| ----------- | ---------------------------------- | ------- | ------ | +| HTTP 状态码 | 判断接口调用是否成功(200 或 404) | Integer | 必须 | + +#### 响应主体 + +| 返回参数 | 用途 | 类型 | 必要性 | +| ------------ | -------------------- | -------------------- | ---------------------- | +| ResponseData | 各个接口的业务数据 | object(依据接口而异) | 必须 | +| Error | 错误 code 和错误信息 | ErrorInfo | 非必须 ,无错误时不返回 | + +``` +{ + "ResponseData": { + app_id: "xxxx", + StatusReason: { + Code: "Requirement.NotEnough", + Message: "Insufficient system resources (cpu, memory, disk space).", + Detail: "Error detail information" + } + }, + "Error": { + Code: "Requirement.NotEnough", + Message: "Insufficient system resources (cpu, memory, disk space).", + Detail: "Error detail information" + } +} +``` + +#### 错误代码设计 + +错误代码参考 [AWS API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html) 的分类方式: + +- Client errors: These errors are usually caused by something the client did, such as specifying an incorrect or invalid parameter in the request, or using an action or resource on behalf of a user that doesn't have permission to use the action or resource. These errors are accompanied by a 400-series HTTP response code. + +- Server errors: These errors are usually caused by an AWS server-side issue. These errors are accompanied by a 500-series HTTP response code. + +##### Client errors + +| code | message | detail | +| ------------------------------------- | -------------- | ------ | +| Client.Parameter.Blank.Error | p 必填参数为空 | null | +| Client.Parameter.Format.Error | p 参数语法不符 | null | +| Client.Parameter.Value.NotExist.Error | p 参数值错误 | null | +| Client.Parameter.Value.Repeat.Error | p 参数值重复 | null | + +##### Server errors + +| code | message | detail | +| ---------------------- | ---------------------- | ------------ | +| Server.Container.Error | Docker 返回原始错误 | 错误详细信息 | +| Server.SystemError | 系统原始错误 | 错误详细信息 | +| Server.\*\*\* | 其他可以友好提示的错误 | 错误详细信息 | + +## 业务接口详情 + +各个业务接口的详细说明,公共参数不在这里继续说明。 + +### App 安装 + +#### Action + +AppInstall + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| ----------------- | ------------------ | ------ | ------ | +| app_name | 应用名称 | string | 必须 | +| customer_app_name | 用户自定义应用名称 | string | 必须 | +| app_version | 应用版本 | string | 必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ------------- | ------ | +| ResponseData | String(AppID) | 必须 | +| Error | ErrorInfo | 非必须 | + +### App 卸载 + +#### Action + +AppUninstall + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | ---------- | ------ | ------ | +| app_id | 卸载该 app | string | 必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ------------- | ------ | +| ResponseData | String(AppID) | 必须 | +| error | ErrorInfo | 非必须 | + +### App 重启 + +#### Action + +AppRestart + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | ---------- | ------ | ------ | +| app_id | 重启该 app | string | 必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ------------- | ------ | +| ResponseData | String(AppID) | 必须 | +| error | ErrorInfo | 非必须 | + +### App 启动 + +#### Action + +AppStart + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | ---------- | ------ | ------ | +| app_id | 启动该 app | string | 必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ------------- | ------ | +| ResponseData | String(AppID) | 必须 | +| error | ErrorInfo | 非必须 | + +### App 停止 + +#### Action + +AppStop + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | ---------- | ------ | ------ | +| app_id | 停止该 app | string | 必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ------------- | ------ | +| ResponseData | String(AppID) | 必须 | +| error | ErrorInfo | 非必须 | + +### App 状态查询 + +#### Action + +AppStatus + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | ----------------- | ------ | ------ | +| app_id | 查询该 app 的信息 | string | 必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ------------- | ------ | +| ResponseData | AppStatusInfo | 必须 | +| error | ErrorInfo | 非必须 | + +AppStatusInfo 说明: + +``` +{ + +  app_id:应用ID, + +  status:应用运行状态,[installing(创建中),running(运行中),exited(停止),restarting(反复重启),failed(失败)] + + status_reason:{ // 只有failed时才有内容 + Code:错误代码 + Message:错误提示信息 + Detail:错误真实信息 + } +   +} +``` + +### App 列表查询 + +#### Action + +AppList + +#### 请求参数 + +| 参数名称 | 用途 | 类型 | 必要性 | +| -------- | -------------- | ------ | ------ | +| app_id | 查询指定的 app | string | 非必须 | + +#### 返回结果 + +| 返回值 | 类型 | 必要性 | +| ------------ | ---------------------- | ------ | +| ResponseData | Array of AppDetailInfo | 必须 | +| error | ErrorInfo | 非必须 | + +AppDetailInfo 说明: + +``` +{ + +  app_id:应用ID, + +  name:应用名, + +  customer_name:自定义应用名, + +  trade_mark:应用商标, + +  status:应用运行状态,[installing(创建中),running(运行中),exited(停止),restarting(反复重启),failed(失败)] + + status_reason:{ // 只有failed时才有内容 + Code:错误代码 + Message:错误提示信息 + Detail:错误真实信息 + }, + + official_app:是否为官方应用, + + image_url:图片路径, + + running_info: { // 只有status=running才有值,其他时候为空 + + port:应用端口, + +   compose_file:docker compose文件路径, + +   url:应用网址, + + admin_url:管理员网址, + +   user_name:用户名, + +   password:密码, + + default_domain: 默认域名, + + set_domain: 用户自定义域名, + } +   +} +``` diff --git a/appmanage/docs/administrator.md b/appmanage/docs/administrator.md deleted file mode 100644 index cdce5042..00000000 --- a/appmanage/docs/administrator.md +++ /dev/null @@ -1,22 +0,0 @@ -# Administrator 管理手册 - -## 环境 - -### 安装组件 - -1. python 环境 - 确保安装 python3.6+ - -2. python 的 pip 包 fastapi,uvicorn[standard],gunicorn - -``` -pip install -r requirements.txt -``` - -3. 安装 docker 以及 docker compose、创建 docker 网络 websoft9 - -### 启动 - -``` -git clone https://github.com/Websoft9/stackhub.git && cd stackhub/docker/appmanage && docker compose up -d -``` diff --git a/appmanage/docs/architecture.md b/appmanage/docs/architecture.md index c47b4d52..a63233ab 100644 --- a/appmanage/docs/architecture.md +++ b/appmanage/docs/architecture.md @@ -1,37 +1,82 @@ -# appmanage +# Architecture -![image](https://user-images.githubusercontent.com/43192516/231104572-a57940b1-273b-4761-ae82-7139a8966f70.png) +AppManage is develop by Python3.10, use [FastAPI](https://github.com/Websoft9/stackhub/blob/main/appmanage/docs/developer.md), [RQ](https://python-rq.org/), logging packages and Redis, Sqlite for data storage + +It have the privilege of host machine, and running below jobs on host: + +* docker and docker compose +* modify file -## RQ +## Asynchronous jobs - RQ -### 设计 +Create application by docker some time need many time, so we use [RQ](https://python-rq.org/) for queueing jobs and processing them in the background with workers -RQ 用于异步处理**创建应用**的事务任务,需保证任务成功或失败后续处理。 - -它提供的状态有: - -- creating: 创建中 -- failed: 创建失败 +![image](images/rq.png) -### RQ status +RQ sample for development: -RQ 主要解决创建应用的状态 +``` +# Job started +rq worker --url redis://websoft9-redis:6379/0 -![image](https://user-images.githubusercontent.com/43192516/231103506-22bbfc80-f31f-4ba0-a331-4a05a345ec25.png) +# RQ 队列创建: +## 指定 Redis 容器的主机名和端口 +redis_conn = Redis(host='websoft9-redis', port=6379) -## docker compose status +## 使用指定的 Redis 连接创建 RQ 队列 +q = Queue(connection=redis_conn,default_timeout=3600) -- running: 运行中 -- exited: 停止 -- restarting: 重启 -- created: 创建失败 +#RQ 队列新增排队任务: +q.enqueue(install_app_delay, app_name, customer_name, app_version, job_id=app_id) -## API status +#获取队列中任务的信息: +## 获取 StartedJobRegistry 实例 +started = StartedJobRegistry(queue=q) +finish = FinishedJobRegistry(queue=q) +deferred = DeferredJobRegistry(queue=q) +failed = FailedJobRegistry(queue=q) +scheduled = ScheduledJobRegistry(queue=q) +cancel = CanceledJobRegistry(queue=q) + +## 获取正在执行的作业 ID 列表 +run_job_ids = started.get_job_ids() +finish_job_ids = finish.get_job_ids() +wait_job_ids = deferred.get_job_ids() +failed_jobs = failed.get_job_ids() +scheduled_jobs = scheduled.get_job_ids() +cancel_jobs = cancel.get_job_ids() +``` + +## Logs partition + + ``` + logPath = 'logs/' + if not os.path.exists(logPath): + os.makedirs(logPath) + logName = 'app_manage.log' + logFile = logPath + logName + formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s') + # handler + time_rotating_file_handler = handlers.TimedRotatingFileHandler(filename=logFile, when="MIDNIGHT", interval=1, encoding='utf-8') + time_rotating_file_handler.setLevel(logging.DEBUG) + time_rotating_file_handler.setFormatter(formatter) + ``` + +## Application Status + +Application status is very import for developer to understand AppManage, it combine the [Docker compose status](https://docs.docker.com/engine/reference/commandline/compose_ps/#options) and [RQ status](https://python-rq.org/docs/job_registries/) - installing(创建中): 来源于 RQ 的queue或StartedJobRegistry, 可进行操作[无法进行任何操作] - running(运行中): 来源于docker compose,可进行操作[所有操作] - exited(停止): 来源于docker compose,可进行操作[Start,Restart,Uninstall,日志查看] - restarting(反复重启): 来源于docker compose,可进行操作[Stop,Restart,Uninstall,日志查看] - failed(失败): 来源于 docker compose 中的 created || RQ 的 FailedJobRegistry 可进行操作[Uninstall] + +> docker compose have status: [paused | restarting | removing | running | dead | created | exited] + + +## API + +FastAPI can create API and API docs of swagger, you can get [API design details](API-design.md) \ No newline at end of file diff --git a/appmanage/docs/developer.md b/appmanage/docs/developer.md index 222e6c5e..b4436265 100644 --- a/appmanage/docs/developer.md +++ b/appmanage/docs/developer.md @@ -1,289 +1,19 @@ -# API 设计文档 +# Developer -## API 结构 +## Deployment -### 请求 - -#### 请求方式 - -支持如下两种调用方式: - -- get -- post - -#### 请求头(公共参数) - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | ------------ | ------ | ------ | -| Version | 接口版本 | string | 可选 | -| Language | 接口显示语言 | string | 可选 | - -#### 安全验证 - -本微服务没有安全验证模块,需通过 API 网关实现 - -#### 请求主体 - -[业务接口详情](#业务接口详情) - -### 响应结果 - -#### 响应头(公共参数) - -| 返回参数 | 用途 | 类型 | 必要性 | -| ----------- | ---------------------------------- | ------- | ------ | -| HTTP 状态码 | 判断接口调用是否成功(200 或 404) | Integer | 必须 | - -#### 响应主体 - -| 返回参数 | 用途 | 类型 | 必要性 | -| ------------ | -------------------- | -------------------- | ---------------------- | -| ResponseData | 各个接口的业务数据 | object(依据接口而异) | 必须 | -| Error | 错误 code 和错误信息 | ErrorInfo | 非必须 ,无错误时不返回 | +Install python3.6+ and Docker, then ``` -{ - "ResponseData": { - app_id: "xxxx", - StatusReason: { - Code: "Requirement.NotEnough", - Message: "Insufficient system resources (cpu, memory, disk space).", - Detail: "Error detail information" - } - }, - "Error": { - Code: "Requirement.NotEnough", - Message: "Insufficient system resources (cpu, memory, disk space).", - Detail: "Error detail information" - } -} +pip install -r requirements.txt +docker network create websoft9 +git clone https://github.com/Websoft9/stackhub.git && cd stackhub/docker/appmanage && docker compose up -d ``` -#### 错误代码设计 +## API UI -错误代码参考 [AWS API](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/errors-overview.html) 的分类方式: +Access API by: **http://Internet IP:port/docs** -- Client errors: These errors are usually caused by something the client did, such as specifying an incorrect or invalid parameter in the request, or using an action or resource on behalf of a user that doesn't have permission to use the action or resource. These errors are accompanied by a 400-series HTTP response code. +### Test Automation -- Server errors: These errors are usually caused by an AWS server-side issue. These errors are accompanied by a 500-series HTTP response code. - -##### Client errors - -| code | message | detail | -| ------------------------------------- | -------------- | ------ | -| Client.Parameter.Blank.Error | p 必填参数为空 | null | -| Client.Parameter.Format.Error | p 参数语法不符 | null | -| Client.Parameter.Value.NotExist.Error | p 参数值错误 | null | -| Client.Parameter.Value.Repeat.Error | p 参数值重复 | null | - -##### Server errors - -| code | message | detail | -| ---------------------- | ---------------------- | ------------ | -| Server.Container.Error | Docker 返回原始错误 | 错误详细信息 | -| Server.SystemError | 系统原始错误 | 错误详细信息 | -| Server.\*\*\* | 其他可以友好提示的错误 | 错误详细信息 | - -## 业务接口详情 - -各个业务接口的详细说明,公共参数不在这里继续说明。 - -### App 安装 - -#### Action - -AppInstall - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| ----------------- | ------------------ | ------ | ------ | -| app_name | 应用名称 | string | 必须 | -| customer_app_name | 用户自定义应用名称 | string | 必须 | -| app_version | 应用版本 | string | 必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ------------- | ------ | -| ResponseData | String(AppID) | 必须 | -| Error | ErrorInfo | 非必须 | - -### App 卸载 - -#### Action - -AppUninstall - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | ---------- | ------ | ------ | -| app_id | 卸载该 app | string | 必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ------------- | ------ | -| ResponseData | String(AppID) | 必须 | -| error | ErrorInfo | 非必须 | - -### App 重启 - -#### Action - -AppRestart - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | ---------- | ------ | ------ | -| app_id | 重启该 app | string | 必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ------------- | ------ | -| ResponseData | String(AppID) | 必须 | -| error | ErrorInfo | 非必须 | - -### App 启动 - -#### Action - -AppStart - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | ---------- | ------ | ------ | -| app_id | 启动该 app | string | 必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ------------- | ------ | -| ResponseData | String(AppID) | 必须 | -| error | ErrorInfo | 非必须 | - -### App 停止 - -#### Action - -AppStop - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | ---------- | ------ | ------ | -| app_id | 停止该 app | string | 必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ------------- | ------ | -| ResponseData | String(AppID) | 必须 | -| error | ErrorInfo | 非必须 | - -### App 状态查询 - -#### Action - -AppStatus - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | ----------------- | ------ | ------ | -| app_id | 查询该 app 的信息 | string | 必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ------------- | ------ | -| ResponseData | AppStatusInfo | 必须 | -| error | ErrorInfo | 非必须 | - -AppStatusInfo 说明: - -``` -{ - -  app_id:应用ID, - -  status:应用运行状态,[installing(创建中),running(运行中),exited(停止),restarting(反复重启),failed(失败)] - - status_reason:{ // 只有failed时才有内容 - Code:错误代码 - Message:错误提示信息 - Detail:错误真实信息 - } -   -} -``` - -### App 列表查询 - -#### Action - -AppList - -#### 请求参数 - -| 参数名称 | 用途 | 类型 | 必要性 | -| -------- | -------------- | ------ | ------ | -| app_id | 查询指定的 app | string | 非必须 | - -#### 返回结果 - -| 返回值 | 类型 | 必要性 | -| ------------ | ---------------------- | ------ | -| ResponseData | Array of AppDetailInfo | 必须 | -| error | ErrorInfo | 非必须 | - -AppDetailInfo 说明: - -``` -{ - -  app_id:应用ID, - -  name:应用名, - -  customer_name:自定义应用名, - -  trade_mark:应用商标, - -  status:应用运行状态,[installing(创建中),running(运行中),exited(停止),restarting(反复重启),failed(失败)] - - status_reason:{ // 只有failed时才有内容 - Code:错误代码 - Message:错误提示信息 - Detail:错误真实信息 - }, - - official_app:是否为官方应用, - - image_url:图片路径, - - running_info: { // 只有status=running才有值,其他时候为空 - - port:应用端口, - -   compose_file:docker compose文件路径, - -   url:应用网址, - - admin_url:管理员网址, - -   user_name:用户名, - -   password:密码, - - default_domain: 默认域名, - - set_domain: 用户自定义域名, - } -   -} -``` +Coming soon... diff --git a/appmanage/docs/guide.md b/appmanage/docs/guide.md deleted file mode 100644 index 3256396f..00000000 --- a/appmanage/docs/guide.md +++ /dev/null @@ -1,9 +0,0 @@ -## 使用 - -### API - -安装 appmanage 后,可使用浏览器或Postman访问接口,自动生成文档地址:http://ip:port/redoc 或 http://ip:port/docs - -### CLI - -暂未提供 diff --git a/appmanage/docs/images/rq.png b/appmanage/docs/images/rq.png new file mode 100644 index 0000000000000000000000000000000000000000..bed376f23b9e94e38498b982a83dabd1021d4fbe GIT binary patch literal 7137 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 literal 0 HcmV?d00001 diff --git a/appmanage/test/README.md b/appmanage/test/README.md new file mode 100644 index 00000000..6ca2f2e8 --- /dev/null +++ b/appmanage/test/README.md @@ -0,0 +1,3 @@ +# Test + +Automatic testing script for API \ No newline at end of file diff --git a/docs/developer.md b/docs/developer.md index 2f99159c..3562c3f8 100644 --- a/docs/developer.md +++ b/docs/developer.md @@ -1,75 +1,6 @@ # Developer Guide -## Appmanage -### 开发环境以及组件 - -Python3.10, FastAPI, RQ, logging - -### 关键技术实现 - -#### 日志分割 - - ``` - logPath = 'logs/' - if not os.path.exists(logPath): - os.makedirs(logPath) - logName = 'app_manage.log' - logFile = logPath + logName - formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s') - # handler - time_rotating_file_handler = handlers.TimedRotatingFileHandler(filename=logFile, when="MIDNIGHT", interval=1, encoding='utf-8') - time_rotating_file_handler.setLevel(logging.DEBUG) - time_rotating_file_handler.setFormatter(formatter) - ``` - -#### RQ - -任务管理器启动: - - ``` - rq worker --url redis://websoft9-redis:6379/0 - ``` - -RQ 队列创建: - - ``` - # 指定 Redis 容器的主机名和端口 - redis_conn = Redis(host='websoft9-redis', port=6379) - - # 使用指定的 Redis 连接创建 RQ 队列 - q = Queue(connection=redis_conn,default_timeout=3600) - ``` - -RQ 队列新增排队任务: - -``` -q.enqueue(install_app_delay, app_name, customer_name, app_version, job_id=app_id) -``` - -获取队列中任务的信息: - -``` -# 获取 StartedJobRegistry 实例 -started = StartedJobRegistry(queue=q) -finish = FinishedJobRegistry(queue=q) -deferred = DeferredJobRegistry(queue=q) -failed = FailedJobRegistry(queue=q) -scheduled = ScheduledJobRegistry(queue=q) -cancel = CanceledJobRegistry(queue=q) - -# 获取正在执行的作业 ID 列表 -run_job_ids = started.get_job_ids() -finish_job_ids = finish.get_job_ids() -wait_job_ids = deferred.get_job_ids() -failed_jobs = failed.get_job_ids() -scheduled_jobs = scheduled.get_job_ids() -cancel_jobs = cancel.get_job_ids() -``` - -### API 文档 - -[FastAPI 文档](https://github.com/Websoft9/stackhub/blob/main/appmanage/docs/developer.md) 使用 swagger 自动生成,访问地址:http://IP:PORT/docs。 ## 版本管理 diff --git a/docs/research.md b/docs/notes/research.md similarity index 100% rename from docs/research.md rename to docs/notes/research.md diff --git a/docs/软件工厂.md b/docs/notes/软件工厂.md similarity index 100% rename from docs/软件工厂.md rename to docs/notes/软件工厂.md diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index e69de29b..00000000