[RFC] egg-cluster 支持 worker_threads 启动模型
## 背景

目前 `worker_threads` API 已经稳定，在 `>= node-v12.x` 的环境下，考虑将原本的基于 `child_process` & `cluster` 的多进程模型之外，提供可选配置 `mode`：
* `default`: 默认值，继续采用基于 process 的多进程启动
* `worker_threads`: 采用基于 `worker_threads` 的启动方案

其中对于在 `worker_threads` 模型下，Node.js 针对每一个线程的 `even_tool` 以及 `v8::Isolate` 均为独立，这样 JavaScript 层面的资源是隔离的，互相之间的通信依靠标准 `html structured clone algorithm` 进行。

更多的，资源限制方面，可以通过 `worker.resourceLimits` 来限制每一个 `worker_threads` 的内存等资源，提供和基于 process 隔离相似的稳定性体验。

一些优势，`worker_threads` 之间的通信是进程内的，对于原本基于 process 的 ipc 或者走本地端口的方案，设计的复杂度和数据交互的性能均可以得到提升，并且基于 `worker_threads` 的 `agent_worker` 和 `app_worker` 数据频繁交互也成为可以在生产使用的方案。

最后在云下资源占用的角度，进程模型下一个 Egg 应用最少需要启动三个进程：`master - app - agent`，线程模型下则实际上只有一个进程，更加适合 serveless 中的低配额场景（例如 < 1c < 1g 的规格）

## 思路

Egg 框架本身 `app_worker` 和 `agent_worker` 的设计无需更改，只需要在 `egg-cluster` 中进行适配即可：

```js
const startCluster = require('egg-cluster').startCluster;

startCluster({
  baseDir: __dirname,
  mode: 'worker_threads'
});
```

具体为将 `egg-cluster` 中原本的进程 `fork` & `cluster` 相关操作进一步抽象为一个 BaseWorker 的原型方法，并提供基于进程和线程对应的 Impl 。

以后如果有更多上层的部署启动模型也可以根据 `mode` 配置依次实现 BaseWorker 的 Impl 即可

## 跟进

* [ ] `egg-cluster` 中的启动模型抽象，增加 `mode` 配置
* [ ]  进程模型的启动逻辑收敛为单独的 Impl
* [ ]  提供基于 `worker_threads` 的 Impl
* [ ] 在上层验证 `worker_threads` mode 是否完全兼容
