Code Monkey home page Code Monkey logo

spec's People

Contributors

beace avatar devxiaolan avatar gemwuu avatar hyj1991 avatar noahziheng avatar thonatos avatar xadillax avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spec's Issues

[RFC] 错误信息标准化 & 友好错误提示

特性描述

  • 提供统一机制给框架 Core、生态插件,按规范(1)抛错
  • 错误信息由 Logger 按规范(2)打印
  • 提供统一平台按规范(3)接受错误信息注册,并供查询

产出内容

  • 统一错误抛出 API 规范(1)
  • 错误信息 API 规范(2)
  • 平台错误记录标准格式 规范(3)

[RFC] 灵活的进程管理模型

特性描述

  • 标准模型为 Master -> App Entry 单进程运行
  • 允许业务层通过 pm2 等工具进行多进程部署
  • 提供类似 @conf-js/cluster 的扩展包进行多进程部署

产出内容

  • 框架核心 Spec 为单进程模型
  • @conf-js/cluster 扩展包

[feat] 支持插件策略类型扩展

许多场景下,私有化部署时需要基于开源 Plugin 进行扩展(例如生命周期),需要提供扩展 Plugin 私有化的能力,而非只能 fork 代码全量修改后发包。

例如开源版本的 @artus/mysql,本土化部署时 mysql 连接前需要进行一些异步定制操作再继续,希望无需 fork @artus/mysql 代码,而是编写一个 @private/mysql 继承 @artus/mysql 进行扩展,这样开源版本的 @artus/mysql 即作为 Npm 依赖位于 @private/mysql 中,只需要关注扩展的私有定制逻辑即可。

[RFC] 多样化构建结果

特性描述

  • 使用 tsc/不构建 形式,产出传统 Node.js 工程
  • 通过 swc/esbuild 等工具,加速构建环节/本地开发,产出传统 Node.js 工程
  • 通过 webpack 复用前端生态,产出单文件,用于 Serverless/WebAssembly 等场景
  • 以上特性通过 CLI 的配置文件决定
// framework-cli.config.ts
export default {
   port: 3000,
   build: {
     	 engine: 'swc',
       bundle: true, // Single file bundle
   },
   devServer: {
       hmr: true,
   }
}

[RFC] 框架核心功能独立

  • 框架核心功能允许独立使用,可以无server模式使用,以满足timer, MQ Consumer 等场景可以利用框架的能力
  • 提供基础框架的能力,业务方可以定制自己的业务模型框架

[RFC] 增加构建/运行时元信息目录约束

考虑增加以下两个明确的路径约束:

  • 构建目标目录 .build
    • 构建结果文件
    • manifest.json
    • ...
  • 运行时元信息文件目录 .run
    • 启动日志
    • 故障排查文件
      • 计算后的 config 结果
      • 生效的 plugin 列表

[RFC] 增加 ExceptionFilter 机制,统一异常处理流

初版 Spec 中,我们约定了 Exception 的声明、抛出机制;
但捕获一节仅保留了临时的 onerror 实现,受制于 Koa 执行机制,并不完善,因此并未直接实现。

在上层框架开发实践中,我们发现,对于用户需要关注的异常大致有两类:

  • 作用域在 Singleton 的异常
    • 通常在生命周期中抛出
    • 大多会被/有机会被显式 try-catch
    • 剩余需要被框架主动处理(通常是:打点、打日志、通知 Daemon、退出进程)
  • 作用域在 Execution 的异常
    • 通常在业务代码中抛出
    • 大多不适合被显式 try-catch(执行时机、代码冗余)
    • 业务需要关心并主动进行处理(通常协议有关,如返回响应状态码、JSON 错误结构体)
    • 一般与中间件有关
    • 需要提供一套命名为 ExceptionFilter 的机制来用于在执行期处理

机制需要包括:

  • 提供 Interface 用于编码实践,Filter 实体放入 IoC 容器
  • 提供基于配置的注册机制,用于执行单元获取实体信息
  • TriggerExceptionHandler 中增加公共逻辑,用于统一执行 Filter
  • 提供元信息语法糖用于处理指定错误码/错误实体的错误

需讨论的模糊问题:

  • 不希望过度冲击已有的中间件序列(有用户习惯使用中间件处理错误,且经常不抛出),思路有二:
    • 只在 Trigger 中增加特殊处理,在执行流最末尾执行 Filter
    • 增加 ExceptionHandler.throw 处理逻辑,API 抛出后立即执行 Filter(是 ExceptionHandler 设计本意)
      • 会冲击中间件序列中的 catch 逻辑
      • 为了保证 throw xxx 仍然也能正常执行,Trigger 中的 catch 仍需存在
  • 为了与中间件处理错误有所差异,不考虑引入 ctx,单个 Filter 不应关心其他 Filter,那就有可能出现多个 Filter 重复执行对协议响应的操作,有解法如下:
    • Filter 全部依序执行,为单个 Filter 提供类似 done() 的 API,主动终止执行序列(API 不优雅)
    • 规定通用的、针对单个错误码/实体的 Filter 唯一,不允许存在多个(通用性受限)

Spec 修改草案见 #27 中的 Markdown

[RFC] 插件能力设计及生态

能力设计

  • 业务逻辑层面
    • 插件应该是一个完整的应用 min-application,允许参与路由控制、支持业务逻辑、插件中使用中间件等。
  • 插件使用
    • 保持可插拔的特性,开发者应该能够在框架层面控制插件的 enabledisable
    • 个人认为插件可以相互保持依赖关系(执行顺序的依赖关系),但是要降低互相引用,保持相对独立(这里可能是个值得讨论的点)。
    • 屏蔽内部实现细节,只对外暴露整体,面向开发者一键使用。
  • 插件API
    • 涉及到插件开发,需要存在这样一个 PluginBase 基类,入口类似的 applycreate 方法。
    • 同样的,如果是一个完备的应用,需要具有 /service /middleware 能力

插件生态

  • 插件开发
    • 降低插件开发门槛,保持插件开发的透明度。提供一套完整的插件 boilerplate 规范,以及开发插件注入、测试、集成方法,甚至包含插件发布的工具链。
  • 插件市场
    • 搭建插件市场,类似的 gatsbyjs plugin 形式。进行一些归类,大类上可以分为官方及社区。
    • 必要时在业务框架中内置核心或者说常用插件,也需要支持用户自建私有插件库。
    • 搭建插件社区,透露一些插件使用频率(npm 下载量、issue 个数、活跃程度等),官方可以提供一定程度的插件审核、review、推广,这块偏运营。

[RFC] 支持类中间件与函数中间件

背景

形似 koa 的中间件无法使用 inject 进行注入,使用上与 service 无法对齐;故而新增中间件类型:

  • 类中间件:在类添加 @Middleware({ enable: true }) 注解
  • 函数中间件:在对应的 http method 上添加 @MV({ middlewares: [] }) 注解

需要考虑一下是否在 @artus/pipeline 中添加对类中间件支持?

实现

示例

类中间件

对于全局中间件,参考 nestjs 的语法,支持 Middleware 注解,参数为是否启用,通过 pipeline.run(ctx) 运行

import { ArtusInjectEnum, Inject } from '@artus/core';
import { ArtusxContext, ArtusxNext, Middleware } from '@artusx/core';

@Middleware({
  enable: true,
})
export default class CheckAuthMiddleware {
  @Inject(ArtusInjectEnum.Config)
  config: Record<string, string | number>;

  async use(ctx: ArtusxContext, next: ArtusxNext): Promise<void> {
    const { data } = ctx.context.output;
    data.authed = false;
    console.log('middleware - checkAuth', ctx.context, this.config);
    await next();
  }
}

函数中间件

函数中间件,在 http method 中使用,接收参数为函数中间件数组,通过 koa.use(middlewares) 方式运行

middleware.ts

import { ArtusxContext, ArtusxNext } from '@artusx/core';

export default async function traceTime(_ctx: ArtusxContext, next: ArtusxNext): Promise<void> {
  console.time('trace');
  await next();
  console.timeEnd('trace');
}

controller.ts

import { ArtusInjectEnum, Inject } from '@artus/core';
import { GET, POST, Controller, MW } from '@artusx/core';
import type { ArtusxContext } from '@artusx/core';

import traceTime from '../middleware/traceTime';

@Controller()
export default class HomeController {
  @Inject(ArtusInjectEnum.Config)
  config: Record<string, string | number>;

  @MW([traceTime])
  @GET('/')
  async home(ctx: ArtusxContext) {
    ctx.body = 'home';
  }
}

[RFC] 完善文档和插件生态

背景

使用文档

开发者&用户需要通过 core 的测试用例才能了解如何开发插件以及应用;对于 scanner / loader / plugin 机制,文档的介绍也相对的比较简单,仍然需要进一步参考示例才能更好的使用。

社区生态

artus 的设计理念,无需项目提供太多插件;但对于使用者而言,从零到一并不容易,故而仍然需要提供一些常用插件,便于用户快速的使用并且了解框架设计。

计划

使用文档

https://www.artusjs.org/

除当前核心概念的解释外,增加开发者 、用户视角的使用文档

社区生态

https://github.com/artusjs/artusx

通过 x 项目提供社区常见服务如 koa / express 插件,以及使用示例,便于大家使用快速上手

[RFC] 底层协议无关

讨论下怎么抽象交互模型,下面是我目前的一些想法。

底层协议无关并不是没有任何限制,这里可能依旧主要面向 C/S 的交互场景(或者有更好的想法):

  • 请求 - 响应模型
  • 单独的请求模型(无响应)
  • 单独的响应模型(无请求)

目前的 C/S 的交互场景自身是存在一些可以抽象出来的公共特征,以及流水线式的逻辑处理天然有统一的切面处理需求,结合目前版本的实践,进一步进行可扩展的设计:

  • 抽象 BaseContext
    • HttpContext / RpcContext / UdpContext / WebSocketContext / ThriftContext 根据协议自行扩展
  • 抽象 BaseTrigger + 洋葱中间件模型
    • Trigger 作为中间件入口触发器,不同协议可以自行扩展加一些定制信息

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.