Skip to content

Commit

Permalink
refactor: 将 db accessor 并到 Globals 管理;
Browse files Browse the repository at this point in the history
  • Loading branch information
maslow committed Jul 24, 2021
1 parent a62ed37 commit 3fba6a9
Show file tree
Hide file tree
Showing 21 changed files with 169 additions and 69 deletions.
3 changes: 2 additions & 1 deletion src/api/function-log.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { db } from "../lib/db"
import { Globals } from "../lib/globals"

const db = Globals.db

/**
* 添加函数执行日志
Expand Down
3 changes: 2 additions & 1 deletion src/api/function.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { db } from "../lib/db"
import { Globals } from "../lib/globals"

const db = Globals.db

/**
* 根据函数名获取云函数
Expand Down
4 changes: 3 additions & 1 deletion src/api/permission.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

import * as assert from 'assert'
import { db } from '../lib/db'
import { Globals } from '../lib/globals'

const db = Globals.db

/**
* 判断用户是否有权限
Expand Down
7 changes: 4 additions & 3 deletions src/api/rules.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as assert from 'assert'
import { Ruler } from 'less-api'
import { accessor, db } from '../lib/db'
import { entry as adminEntry } from '../router/entry/admin'
import { entry as appEntry } from '../router/entry/app'
import { Globals } from "../lib/globals"

const db = Globals.db
export interface RuleDocument {
category: string,
collection: string,
Expand Down Expand Up @@ -34,15 +35,15 @@ export async function getAccessRules(category: string): Promise<any> {
export async function applyRules() {
// apply admin rules
{
const ruler = new Ruler(accessor)
const ruler = new Ruler(Globals.accessor)
const rules = await getAccessRules('admin')
ruler.load(rules)
adminEntry.setRuler(ruler)
}

// apply app rules
{
const ruler = new Ruler(accessor)
const ruler = new Ruler(Globals.accessor)
const rules = await getAccessRules('app')
ruler.load(rules)
appEntry.setRuler(ruler)
Expand Down
3 changes: 2 additions & 1 deletion src/api/trigger.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { db } from "../lib/db"
import { Globals } from "../lib/globals"

const db = Globals.db

/**
* 请求触发器列表
Expand Down
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import * as express from 'express'
import { parseToken } from './lib/utils/token'
import { router } from './router/index'
import { v4 as uuidv4 } from 'uuid'
import { getLogger } from './lib/logger'
import Config from './config'
import { router } from './router/index'
import { Globals } from './lib/globals'


const logger = getLogger('server')
const logger = Globals.logger
const server = express()
server.use(express.json())

Expand Down
20 changes: 0 additions & 20 deletions src/lib/db.ts

This file was deleted.

10 changes: 5 additions & 5 deletions src/lib/faas/function.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { FunctionEngine } from "."
import { accessor, createDb } from '../db'
import { LocalFileStorage } from "../storage/local_file_storage"
import request from 'axios'
import Config from "../../config"
import { CloudFunctionStruct, CloudSdkInterface, FunctionContext, FunctionResult } from "./types"
import { getToken, parseToken } from "../utils/token"
import * as ts from 'typescript'
import { FunctionConsole } from "./console"
import { scheduler } from "../scheduler"
import { getFunctionByName } from "../../api/function"
import { Globals } from "../globals"
import { Scheduler } from "../scheduler"

export class CloudFunction {
// 跨请求、跨函数的全局配置对象,单例(in memory)
Expand Down Expand Up @@ -103,15 +103,15 @@ export class CloudFunction {
*/
createCloudSdk(): CloudSdkInterface {
const cloud: CloudSdkInterface = {
database: () => createDb(),
database: () => Globals.createDb(),
storage: (namespace: string) => new LocalFileStorage(Config.LOCAL_STORAGE_ROOT_PATH, namespace),
fetch: request,
invoke: this.invokeInFunction.bind(this),
emit: (event: string, param: any) => scheduler.emit(event, param),
emit: (event: string, param: any) => Scheduler.emit(event, param),
shared: CloudFunction._shared_preference,
getToken: getToken,
parseToken: parseToken,
mongodb: accessor.db
mongodb: Globals.accessor.db
}

return cloud
Expand Down
6 changes: 3 additions & 3 deletions src/lib/faas/trigger-scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getLogger } from "../logger"
import { createLogger } from "../logger"
import { now } from "../utils/time"
import { FunctionContext } from "./types"
import { CloudFunction } from "./function"
Expand All @@ -7,12 +7,12 @@ import { addFunctionLog } from "../../api/function-log"
import { getFunctionById } from "../../api/function"


const logger = getLogger('trigger')
const logger = createLogger('trigger')


/**
* 触发器管理
* 触发器类型:event, timer, http
* 触发器类型:event, timer
*/
export class TriggerScheduler {
private _triggers: Trigger[] = []
Expand Down
4 changes: 2 additions & 2 deletions src/lib/faas/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { FunctionConsole } from "./console"
import { AxiosStatic } from 'axios'
import { Db } from 'less-api-database'
import { FileStorageInterface } from "../storage/interface"
import { IncomingHttpHeaders } from "node:http"
import { IncomingHttpHeaders } from "http"
import * as mongodb from "mongodb"

export type RequireFuncType = (module: string) => any
export type InvokeFunctionType = (name: string, param: FunctionContext) => Promise<any>
export type InvokeFunctionType = (name: string, param: FunctionContext) => Promise<FunctionResult>
export type EmitFunctionType = (event: string, param: any) => void
export type GetTokenFunctionType = (payload: any) => string
export type ParseTokenFunctionType = (token: string) => any | null
Expand Down
84 changes: 84 additions & 0 deletions src/lib/globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@


import { MongoAccessor, getDb, LoggerInterface } from 'less-api'
import { Db } from 'less-api-database'
import Config from '../config'
import { createLogger } from './logger'

/**
* 管理应用的全局对象
*/
export class Globals {
private static _accessor: MongoAccessor = null
private static _db: Db = null
private static _logger: LoggerInterface = null

static get accessor() {
return this._accessor
}

static get db() {
return this._db
}

static get logger() {
return this._logger
}

/**
* 初始化全局对象
*/
static init() {
// 创建全局日志对象
if (null === this._logger) {
this._logger = createLogger('server')
}

// 创建 app db accessor
if (null === this._accessor) {
this._accessor = this._createAccessor()
}

// 创建 Db ORM 实例
if (null === this._db) {
this._db = this.createDb()
}

Object.freeze(Globals)
}


/**
* 创建 Db 实例
* @returns
*/
static createDb() {
if (null === this._accessor) {
throw new Error('Globals.accessor is empty, please run Globals.init() before!')
}
return getDb(this._accessor)
}


/**
* 创建 MongoAccessor 对象
* @returns
*/
private static _createAccessor() {
const accessor = new MongoAccessor(Config.db.database, Config.db.uri, {
poolSize: Config.db.poolSize,
useNewUrlParser: true,
useUnifiedTopology: true
})

accessor.setLogger(createLogger('db', 'warning'))
accessor.init()

return accessor
}
}

/**
* 初始化全局资源对象
*/
Globals.init()
2 changes: 1 addition & 1 deletion src/lib/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as log4js from 'log4js'
import Config from '../config'


export function getLogger(category: string, level?: string): LoggerInterface {
export function createLogger(category: string, level?: string): LoggerInterface {
const logger = log4js.getLogger(category)
logger.level = level ?? Config.LOG_LEVEL

Expand Down
11 changes: 6 additions & 5 deletions src/lib/scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { getLogger } from "log4js"
import { getTriggers } from "../api/trigger"
import { accessor } from "./db"
import { TriggerScheduler } from "./faas"
import { Trigger } from "./faas/trigger"
import { Globals } from "./globals"
import { convertActionType } from "./utils"

const accessor = Globals.accessor
const logger = getLogger('scheduler')

// 触发器的调度器单例
export const scheduler = new TriggerScheduler()
export const Scheduler = new TriggerScheduler()

// 当数据库连接成功时,初始化 scheduler
accessor.ready.then(async () => {
Expand All @@ -17,9 +18,9 @@ accessor.ready.then(async () => {
logger.debug('loadTriggers: ', data)

const triggers = data.map(data => Trigger.fromJson(data))
scheduler.init(triggers)
Scheduler.init(triggers)

scheduler.emit('app.ready')
Scheduler.emit('app.ready')
})

accessor.on('result', AccessorEventCallBack)
Expand All @@ -43,7 +44,7 @@ export function AccessorEventCallBack(data: any) {

// 触发数据事件
const event = `/db/${params.collection}#${op}`
scheduler.emit(event, {
Scheduler.emit(event, {
exec_params: params,
exec_result: result
})
Expand Down
23 changes: 23 additions & 0 deletions src/lib/utils/lang.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@


/**
* 递归深冻结对象
* @param object
* @returns
*/
export function deepFreeze(object: Object) {
// Retrieve the property names defined on object
const propNames = Object.getOwnPropertyNames(object)

// Freeze properties before freezing self

for (const name of propNames) {
const value = object[name]

if (value && typeof value === "object") {
deepFreeze(value)
}
}

return Object.freeze(object)
}
8 changes: 4 additions & 4 deletions src/router/admin/admin.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Request, Response } from 'express'
import { getToken } from '../../lib/utils/token'
import { db } from '../../lib/db'
import { checkPermission, getPermissions } from '../../api/permission'
import { getLogger } from '../../lib/logger'
import { createLogger } from '../../lib/logger'
import { hashPassword } from '../../lib/utils/hash'
import { Globals } from '../../lib/globals'


const logger = getLogger('admin:api')
const db = Globals.db
const logger = createLogger('admin:api')

/**
* 管理员登陆
Expand Down
4 changes: 2 additions & 2 deletions src/router/admin/rule.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Request, Response } from 'express'
import { checkPermission } from '../../api/permission'
import { getLogger } from '../../lib/logger'
import { createLogger } from '../../lib/logger'
import { applyRules } from '../../api/rules'

const logger = getLogger('admin:api')
const logger = createLogger('admin:api')

/**
* 应用最新访问规则
Expand Down
10 changes: 5 additions & 5 deletions src/router/admin/trigger.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Request, Response } from 'express'
import { checkPermission } from '../../api/permission'
import { getLogger } from '../../lib/logger'
import { scheduler } from '../../lib/scheduler'
import { createLogger } from '../../lib/logger'
import { Trigger } from '../../lib/faas/trigger'
import { getTriggerById, getTriggers } from '../../api/trigger'
import { Scheduler } from '../../lib/scheduler'

const logger = getLogger('admin:api')
const logger = createLogger('admin:api')

/**
* 应用触发器配置
Expand All @@ -30,7 +30,7 @@ export async function handleApplyTrigger(req: Request, res: Response) {
if (!triggerId) {
const data = await getTriggers()
const triggers = data.map(data => Trigger.fromJson(data))
scheduler.init(triggers)
Scheduler.init(triggers)

return res.send({ code: 0, data: 'ok:applied' })
}
Expand All @@ -42,7 +42,7 @@ export async function handleApplyTrigger(req: Request, res: Response) {
}
// 更新指定触发器
const trigger = Trigger.fromJson(data)
const result = scheduler.updateTrigger(trigger)
const result = Scheduler.updateTrigger(trigger)

return res.send({
code: 0,
Expand Down
Loading

0 comments on commit 3fba6a9

Please sign in to comment.