# Develop daemon_console
这是daemon_console库的开发设计文档，旨在明确代码的底层架构设计和工作原理。
> Written only by Chinese Simplified.

这个项目的立项和开发深受MCDReforged的影响，但完全不是为了复刻一个新的MCDR出来，而是抽象其体验和设计并构建出一个更为通用的库以供下游开发扩展。当然你完全可以使用此库设计一个Rust版本的MCDReforged，它或许会比MCDR跑的更快。

MCDReforged只能管理Minecraft服务器，尽管它支持管理任何具有输入输出流的程序，但它的大部分代码仅仅针对Minecraft服务端本身进行设计。而此项目则更为通用和抽象，可以针对任意类型的应用程序进行功能适配，并且基于Rust会更快更安全。

## 项目结构
本项目设计为一个“守护进程控制台”，为后续开发者为自己的项目设计具有日志输出和命令输入功能的Rust守护进程时提供便利。

将此项目集成到更具实用功能的项目中是推荐的做法。

为此`src/lib.rs`设计了一整套接口，实现直观的前台控制台体验。

### 前台界面
> 体验类似MCDReforged控制台

- 流式日志输出

在用户当前Shell（bash/zsh/fish/.../PowerShell）中滚动输出日志，并在结束时保留打印出的所有内容。

- 命令提示符（命令输入行）

在Shell最底下一行显示一个`> `表示这里是命令输入区，用户在此位置键入命令文本和快捷键。

### 命令系统
提供了一个简单的命令系统，用于响应命令提示符中提交的命令文本内容。

目前已支持同步和异步函数。

## 生命周期
启动`TerminalApp` -> 打印程序运行时日志、响应命令（工作周期） -> 结束程序、清理后台任务最后退出

### 工作周期
在工作周期内，前台和底层运行着不同的任务。这里主要介绍底层的任务管理设计。

- 日志输出

按照固定格式输出程序的运行时消息或命令执行结果。

- 命令响应

持续等待并响应用户提交的命令文本内容。

#### 后台任务管理
> 截至目前没有相关的代码实现。

主要应由下游进行设计，但这里详细介绍下此项目将实现的一些部分。
Daemon Console将设置不同的线程，以运行不同类型的任务负载。

- Daemon Console主线程
> 这是一个概念性设计，实际上就是`main`线程。

包括前台整个控制台界面的渲染和`TerminalApp`接口的运行时。

主线程启动并管理其他所有线程。

- 任务执行者线程：TaskExecutor

为下游甚至下游的插件插件串行执行daemon_console库提供的所有公开的同步方法。
> 若设计和调用不当，可能造成阻塞！

- 异步任务执行者线程：AsyncTaskExecutor

和任务执行者线程类似，但只执行异步代码。

- 下游主线程
> 同样的，这是一个概念性设计。

daemon_console是一个比较底层的库，其目的是为下游项目提供前台控制台界面渲染和命令系统。下游使用这个库将能够设计出类似于MCDReforged这样的一套完整的框架工具。

为此，下游项目会有自己的核心代码运行时。

建议直接扔到任务执行者线程中运行，或者自行维护管理一个单独的线程名称，也可以合并到Daemon Console的逻辑中。Daemon Console将为前两种情况提供一些基础支持。

- 插件运行线程：`PluginThread(<plugin_id>)`

下游项目应该把自己的插件中的任何代码，扔到这个线程里面运行并以插件id等信息完整命名这个线程。这样插件在运行可能造成阻塞的代码时，将不会对其他插件和主线程、任务执行者线程造成影响。

Daemon Console将在退出时最多等待10秒，若这些线程无法正常退出，则强行终止。

- 进程管理线程：SubprocessManager

这是此项目的开发中的核心，利用它你可以像开头提到的那样：实现Rust版本的MCDReforged。

此线程管理Daemon Console或其下游项目启动的所有子进程，这些子进程应像Minecraft服务器一样，具有输入输出流并且输出标准的日志格式。

Daemon Console将把命令提示符提交的命令首先提交到（默认）选定的子进程中，即传递到它的输入流。

子进程应由下游项目进行管理，Daemon Console仅支持执行预设或配置好的命令到子进程中以在退出时停止子进程，如果超过10秒无法停止，则子进程将被强行杀死。

后续Daemon Console还会集成原生的远程管理功能，可以通过ws/wss等协议连接和别的Daemon Console实例共享子进程的输入输出流。

## 动态命令提示符
> 目前的命令提示符太单调，动态命令提示符将动态的显示各种状态信息，更为灵动。仍处于研究阶段。

- 空闲状态

无文本：`> `

有文本：`> help`

- 等待长耗时命令运行中状态

无文本：`(5s)> `
> 长耗时（后台）任务已运行了5秒钟，仍在持续运行。

有文本：`(5s)> help`

- 提示符`>`本身的颜色渲染

之前没有执行过命令、daemon_console实例刚启动时，为白色（没有特别的颜色渲染）。

上一条命令执行顺利，无错误、告警，则完成后渲染成绿色；若上一条命令运行时发生错误则渲染成红色，只是出现警告则渲染成橙（黄）色。

- 输入流重定向

daemon_console设计为多进程管理，因此命令提示符中的命令文本可以被提交到不同的进程中去。

使用`:!spm`或`:daemon_console:spm`选择要重定向输入流的目标子进程，然后提示符将全部渲染成灰色，格式将变为`(子进程名称)> `。
> 渲染成灰色是因为当输入流定向到某个子进程时，daemon_console将无法获取命令的执行情况；输入流重定向后，命令提示符将不再自动选择输入流目标，所有文本除了控制输入流重定向的命令以外，均直接发送到重定向后的子进程的输入流中去；如果可能，将支持使用快捷键回退至智能选择模式，并且实现输入流重定向后使用子进程的Tab补全功能，但可能需要目标子进程重启。

## 仿真终端模拟（PTY）

通过使用PTY相关的库，从技术上Daemon Console将能够兼容像Minecraft等终端程序的Tab补全等需要较为完整的控制台环境的功能特性。
> 目前已证实技术上可以正确捕获日志输出，但Tab补全等功能特性无法正常渲染，仍在进行更多的研究。