Skip to content

Commit

Permalink
Merge opentiny#22 into main from refactor/struct
Browse files Browse the repository at this point in the history
  • Loading branch information
GaoNeng-wWw committed Mar 23, 2024
2 parents 6b95022 + 12aeb25 commit 8ce8341
Show file tree
Hide file tree
Showing 380 changed files with 216 additions and 41,301 deletions.
99 changes: 97 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ ls -al
# .github
# dl-flow-backend // 后端
# dl-flow-frontend // WebUi
# dl-flow.code-workspace
# docker-compose.yaml // 预设好的docker-compose文件
# nginx.conf // 预设好的nginx文件
```
Expand Down Expand Up @@ -146,4 +145,100 @@ cd packages/design-core/dist

### Bug 反馈

如有bug与其他方面的疑问, 欢迎提交[issue](https://atomgit.com/opentiny/000003/issues)
如有bug与其他方面的疑问, 欢迎提交[issue](https://atomgit.com/opentiny/000003/issues)

## 结构

### 流程图

### Web UI

下图展示了项目与TinyEngine的差异文件

```
├── packages
   ├── canvas
   │   ├── src
   │   │   ├── components
   │   │   │   ├── container
   │   │   │   │   ├── AlgoNode.vue // 创建的自定义节点
   │   │   │   │   ├── GroupNode.vue // 组节点
   │   │   │   │   └── X6Canvas.vue // x6容器
   ├── controller
   │   ├── src
   │   │   ├── useLayer.js // 自定义Layer的逻辑
   │   │   ├── useResource.js // 数据请求逻辑
   │   │   ├── useSchema.js // schema逻辑
   │   │   ├── useVisitor.js // Python AST解析
   │   │   ├── useWS.js // socket.io的二次封装
   │   │   └── useX6.js // x6的一些逻辑封装
   ├── design-core
   │   ├── authentication.html
   │   ├── src
   │   │   ├── App.vue
   │   │   └── authentication // 登陆页面
   │   │      └── src
   │   │      ├── App.vue
   │   │      ├── components
   │   │      │   ├── login.vue
   │   │      │   └── register.vue
   │   │      └── main.js
   ├── plugins
   │   ├── materials // 物料 (paddlepaddle的网络物料)
   │   │   └── src
   │   │      ├── Main.vue
   │   │      ├── layer
   │   │      │   └── main.vue
   │   │      └── networks
   │   │      └── main.vue
   │   └── schema // 传输给后端的schema的预览窗
   │   └── src
   │       └── Main.vue
   └── settings // 物料的Props设计页面
      ├── code
      │   └── src
      │      └── Main.vue
      └── props
      ├── index.js
      ├── package.json
      └── src
         ├── Main.vue
         └── components
         ├── Empty.vue
         ├── ParamAttr.vue
         ├── enums.vue
         ├── list.vue
└── property-setting.vue
```

### 后端

[参考](./dl-flow-backend/README.md)


### 为什么结束节点和开始节点必须只有一个

因为目前生成的是`Sequential`而不是`Layer`.

`Layer`的确更加的灵活。但是问题也非常的显而易见。

我们设计的是又向无环图, 又向表明 A->B 是正确的,但是 B->A 是不一定的。假设有一幅图

```
Start
|
v
Node-1
|
-----+-----
| | |
V V V
END1 END2 END3
```

那么不管如何遍历最终节点,其实都是正确的。但在神经网络中,不同网络的运算顺序会有不同的结果。比如`先池化后卷积``先卷积后池化`的运算结果是不同的。进入训练阶段,训练结果也可能不同。这主要是因为函数的组合在某些条件下是不可交换的,我们也使用数学语言证明了这一点。详细可以参考[函数组合的交换性讨论](./dl-flow-backend/proof/函数组合的可交换性讨论.pdf)


## 前端流程图

![](./public/sequenceDiagram.png)
3 changes: 2 additions & 1 deletion dl-flow-backend/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
node_modules
*.md
*.md
proof
92 changes: 86 additions & 6 deletions dl-flow-backend/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,88 @@
# Dl-flow backend
# dl-flow backend

## 如何使用
## 目录结构

1. 确保本机安装了docker
2. 克隆该仓库
3. `cd dl-flow-backend; docker compose up -d `
4. 即可访问
```
├── README.md
├── docker-compose.yaml // 快速启动 compose示例
├── dockerfile // docker构建文件
├── global.d.ts
├── libs
│   ├── database // 数据库模块
│   ├── redis // 缓存模块
│   └── shared // 共用文件
├── src
│   ├── app.module.ts // 主文件
│   ├── auth-guard // token校验门禁 (可以理解为中间件, 不过nest的分类更加细致)
│   ├── code-generate
│   │   ├── ast
│   │   ├── ast.service.ts // ast生成服务
│   │   ├── code-generate.controller.ts // code-generate路由
│   │   ├── code-generate.gateway.ts // code-generate的websocket路由, 不过在nest中叫做gateway
│   │   ├── code-generate.module.ts // code-generate的module
│   │   ├── code-generate.schema.ts // code-generate的schema
│   │   └── code-generate.service.ts // code-generate的服务
│   ├── layer // layer获取与存储的http接口 (没什么技术含量全是CRUD)
│   ├── main.ts
│   ├── material // 物料的获取 (没什么技术含量全是CRUD)
│   ├── user // 用户的登陆注册
│   └── ws-exception // websocket的错误捕获, 主要用于捕获Exception和Runtime Error
├── tsconfig.build.json
├── tsconfig.json
└── webpack.config.js // 打包的配置文件, 主要是定义全局变量
```

### global.d.ts

```typescript
declare global {
namespace NodeJS {
// 为了让process.env.xxx的时候有类型提示
interface ProcessEnv {
DB_URL: string;
REDIS_HOST: string;
REDIS_PORT: number;
REDIS_DB: number;
REDIS_PASSWORD: string;
JWT_EXPIRE_IN: string;
JWT_SIGN_ALGORITHM: JwtSignOptions['algorithm'];
JWT_PUB_KEY: string;
JWT_PRI_KEY: string;
/**
* @deprecated
*/
PWD_SALT: string; // used for bcrypt
PWD_SALT_LEN: string;
}
}
// 开发环境标志
declare const __DEV__: boolean;
// 测试环境标志
declare const __TEST__: boolean;
}
export {};
```


## QA

### 为什么使用的是全局变量而不是环境变量?

`__DEV__``__TEST__`主要是用于测试环境与开发环境。如果一段代码只是测试环境需要(例如准备内存数据库),那么我们可以这么写

```typescript
if (__TEST__){
// do sth
}
```

之后我们只需要在jest的配置文件里的`global`配置项中中,将`__TEST__`定义为`true`就可以了。(详细参考packages.json L94)
而在打包时侯,`webpack`会将`__DEV__``__TEST__`占位符替换为false, 这样一来所有的测试代码与开发调试代码都将会被标记为`dead code`. 最后会被`webpack`自动剔除 (详细参考 webpack.config.js L12-)

### 为什么使用内存数据库而不是MOCK?

mock一组数据是人来mock, 工作量是其次,最主要的问题是难以`靠近实战`. 之所以选择使用内存数据库而不是手动mock, 我给出如下原因

1. 不需要手动mock数据,避免因为人脑无法达到**完全理性**而造成的**数据结构**问题
2. 内存数据库的可维护性很高
3. 数据的销毁简单,不需要本地启动复杂的环境
33 changes: 16 additions & 17 deletions dl-flow-backend/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,22 @@ services:
ports:
- 6379:6379
server:
build:
context: .
dockerfile: Dockerfile
image: gaonengwww/dl-flow-backend
ports:
- 9000:9000
environment:
- DB_URL=mongodb://mongodb:27017/dl-flow
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_DB=0
# - REDIS_PASSWORD=""
# - JWT_EXPIRE_IN=""
# - JWT_SIGN_ALGORITHM=""
- JWT_PUB_KEY=./keys/pub.key
- JWT_PRI_KEY=./keys/pri.key
# - PWD_SALT=""
volumes:
- ./_test/public:/public
- ./_test/keys:/keys
- ./_test/data:/data
- DB_URL=mongodb://mongodb:27017/dl-flow # 数据库地址
- REDIS_HOST=redis # redis地址 (必填)
- REDIS_PORT=6379 # redis端口 (必填)
- REDIS_DB=0 # redis数据库 (必填)
- REDIS_PASSWORD="" # redis密码
- JWT_EXPIRE_IN="1d" # JWT 过期时间 (必填)
- JWT_SIGN_ALGORITHM="RS256" # JWT签名算法, 要与密钥对符合, 例如密钥对是RSA 2048bit, 那么此处应该是 RS256 (必填)
- JWT_PUB_KEY=./keys/key.pub # JWT 公钥 (必填)
- JWT_PRI_KEY=./keys/key.pri # JWT 私钥 (必填)
- PWD_SALT=salt # bcrypt 盐(必填)
- PWD_SALT_LEN=12 # bcrypt 盐(必填)
# volumes: # 强烈将下述卷挂载到本地, 以避免数据丢失
# - ./_test/public:/public # 代码生成暂存位置
# - ./_test/keys:/keys # 密钥对存放位置
# - ./_test/data:/data # bundle.json与install.lock 存放位置
1 change: 1 addition & 0 deletions dl-flow-backend/libs/database/src/database.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { MongooseModule } from '@nestjs/mongoose';
MongooseModule.forRootAsync({
useFactory: async () => {
let uri = process.env.DB_URL;
// 当且仅当为开发环境或测试环境时候,才会去启用内存数据库
if (__DEV__ || __TEST__) {
const { MongoMemoryReplSet } = await import('mongodb-memory-server');
const mongod = await MongoMemoryReplSet.create({
Expand Down
Binary file not shown.
4 changes: 1 addition & 3 deletions dl-flow-backend/src/auth-guard/auth-guard.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,14 @@ export class AuthGuard implements CanActivate {
private redis: Redis,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
if (__DEV__) {
return true;
}
const req = context.switchToHttp().getRequest();
const token = this.extractTokenFromHeader(req);
try {
this.jwt.verify(token);
} catch {
throw new UnauthorizedException();
}
// 如果redis中不存在token, 那么也提示未登陆错误
if (!Boolean(await this.redis.exists(token))) {
throw new UnauthorizedException();
}
Expand Down
9 changes: 9 additions & 0 deletions dl-flow-backend/src/code-generate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# code generate

## 流程图

![](../../../public/3bb36ea8-b6cc-48ae-b227-1118f3b0a4c6.png)

## 附件

[函数组合的可交换性讨论](../../proof/函数组合的可交换性讨论.pdf)
Loading

0 comments on commit 8ce8341

Please sign in to comment.