Skip to content

Commit

Permalink
feat(function): support TTL indexes on logs; support number as return…
Browse files Browse the repository at this point in the history
… value; support result in log;
  • Loading branch information
maslow committed Nov 3, 2021
1 parent 250a9e6 commit fa82cb4
Show file tree
Hide file tree
Showing 19 changed files with 119 additions and 57 deletions.
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ services:
SYS_SERVER_SECRET_SALT: Rewrite_Your_Own_Secret_Salt_abcdefg1234567
SHARED_NETWORK: laf_shared_network
LOG_LEVEL: debug
APP_SERVICE_IMAGE: lafyun/app-service:0.6.5
APP_SERVICE_IMAGE: lafyun/app-service:latest
ACCOUNT_DEFAULT_APP_QUOTA: 5
APP_SERVICE_DEPLOY_HOST: local-dev.host:8080 # `*.local-dev.host` always resolved to 127.0.0.1, used to local development
APP_SERVICE_DEPLOY_URL_SCHEMA: 'http'
DEBUG_BIND_HOST_APP_PATH: '${PWD}/packages/app-service'
# DEBUG_BIND_HOST_APP_PATH: '${PWD}/packages/app-service'
command: npx nodemon
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./packages/system-server:/app
- ./packages/cloud-function-engine:/app/node_modules/cloud-function-engine:ro
- ./packages/cloud-function:/app/node_modules/cloud-function-engine:ro
- ./packages/database-proxy:/app/node_modules/database-proxy:ro
- ./packages/database-ql:/app/node_modules/database-ql:ro
- ./packages/database-ql:/app/node_modules/database-proxy/node_modules/database-ql:ro
Expand Down
7 changes: 5 additions & 2 deletions packages/app-service/src/api/function-log.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* @Author: Maslow<wangfugen@126.com>
* @Date: 2021-07-30 10:30:29
* @LastEditTime: 2021-10-06 19:21:13
* @LastEditTime: 2021-11-03 16:45:06
* @Description:
*/
import { Constants } from "../constants"
Expand All @@ -18,7 +18,10 @@ export async function addFunctionLog(data: any): Promise<any> {

if (!data) return null
const r = await db.collection(Constants.function_log_collection)
.insertOne(data)
.insertOne({
...data,
created_at: new Date()
})

return r.insertedId
}
31 changes: 31 additions & 0 deletions packages/app-service/src/api/indexes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* @Author: Maslow<wangfugen@126.com>
* @Date: 2021-07-30 10:30:29
* @LastEditTime: 2021-11-03 17:06:38
* @Description:
*/
import Config from "../config"
import { Constants } from "../constants"
import { DatabaseAgent } from "../lib/database"

/**
* Add function execution log
* @param data
* @returns
*/
export async function ensureCollectionIndexes(): Promise<any> {
const db = DatabaseAgent.db
await db.collection(Constants.function_log_collection)
.createIndexes([
{
key: { created_at: 1 },
expireAfterSeconds: Config.FUNCTION_LOG_EXPIRED_TIME
},
{
key: { requestId: 1 }
},
{ key: { func_id: 1 } }
])

return true
}
2 changes: 1 addition & 1 deletion packages/app-service/src/cloud-sdk/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


> cloud-sdk 是用于云函数中,做为云函数的 SDK 使用,暴露 less-framework 中的一些资源对象。
> cloud-sdk 是用于云函数中,做为云函数的 SDK 使用,暴露 LaF 中的一些资源对象。
在云函数中使用示例:

Expand Down
2 changes: 1 addition & 1 deletion packages/app-service/src/cloud-sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export interface CloudSdkInterface {
storage(bucket?: string): FileStorageInterface

/**
* 获取 less api database ORM 实例
* 获取 LaF database 实例
*/
database(): Db,

Expand Down
28 changes: 20 additions & 8 deletions packages/app-service/src/cloud-sdk/invoke.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { getFunctionByName } from "../api/function"
import { CloudFunction, FunctionContext } from "cloud-function-engine"
import { addFunctionLog } from "../api/function-log"


/**
Expand All @@ -8,7 +9,7 @@ import { CloudFunction, FunctionContext } from "cloud-function-engine"
* @param param 函数运行参数
* @returns
*/
export async function invokeInFunction(name: string, param: FunctionContext) {
export async function invokeInFunction(name: string, param?: FunctionContext) {
const data = await getFunctionByName(name)
const func = new CloudFunction(data)

Expand All @@ -18,15 +19,26 @@ export async function invokeInFunction(name: string, param: FunctionContext) {

param = param ?? {}

if (param.requestId) {
param.requestId = this.param.requestId
}
param.requestId = param.requestId ?? 'invoke'

if (param.method) {
param.method = param.method ?? 'call'
}
param.method = param.method ?? 'call'

const result = await func.invoke(param)

return result
await addFunctionLog({
requestId: param.requestId,
method: param.method,
func_id: func.id,
func_name: name,
logs: result.logs,
time_usage: result.time_usage,
data: result.data,
error: result.error,
})

if (result.error) {
throw result.error
}

return result.data
}
11 changes: 11 additions & 0 deletions packages/app-service/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,15 @@ export default class Config {
static get isProd(): boolean {
return process.env.NODE_ENV === 'production'
}

/**
* Expired time of function logs, in seconds
*/
static get FUNCTION_LOG_EXPIRED_TIME(): number {
return (process.env.FUNCTION_LOG_EXPIRED_TIME ?? 3600 * 24 * 30) as number
}

static get APP_VERSION(): number {
return process.env.APP_VERSION as any as number
}
}
4 changes: 3 additions & 1 deletion packages/app-service/src/lib/database/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* @Author: Maslow<wangfugen@126.com>
* @Date: 2021-08-16 15:29:15
* @LastEditTime: 2021-10-08 14:34:37
* @LastEditTime: 2021-11-03 17:10:04
* @Description:
*/

Expand All @@ -10,6 +10,7 @@ import { MongoAccessor } from 'database-proxy'
import Config from '../../config'
import { createLogger, logger } from '../logger'
import * as mongodb_uri from 'mongodb-uri'
import { ensureCollectionIndexes } from '../../api/indexes'


/**
Expand Down Expand Up @@ -44,6 +45,7 @@ export class DatabaseAgent {
accessor.init()
.then(async () => {
logger.info('db connected')
await ensureCollectionIndexes()
})
.catch(error => {
logger.error(error)
Expand Down
14 changes: 9 additions & 5 deletions packages/app-service/src/router/function/debug.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* @Author: Maslow<wangfugen@126.com>
* @Date: 2021-07-30 10:30:29
* @LastEditTime: 2021-11-01 18:55:44
* @LastEditTime: 2021-11-03 19:41:03
* @Description:
*/

Expand All @@ -10,6 +10,7 @@ import { FunctionContext, CloudFunction } from 'cloud-function-engine'
import { parseToken } from '../../lib/utils/token'
import { logger } from '../../lib/logger'
import { addFunctionLog } from '../../api/function-log'
import { ObjectId } from 'bson'

/**
* Handler of debugging cloud function
Expand Down Expand Up @@ -51,12 +52,11 @@ export async function handleDebugFunction(req: Request, res: Response) {
// log this execution to db
await addFunctionLog({
requestId: requestId,
func_id: func.id,
method: req.method,
func_id: new ObjectId(func.id),
func_name: func_name,
logs: result.logs,
time_usage: result.time_usage,
created_at: Date.now(),
updated_at: Date.now(),
created_by: req['auth']?.uid,
data: result.data,
error: result.error,
Expand All @@ -76,7 +76,11 @@ export async function handleDebugFunction(req: Request, res: Response) {
logger.trace(requestId, `invoke ${func_name} invoke success: `, result)

if (res.writableEnded === false) {
return res.send(result.data)
let data = result.data
if (typeof result.data === 'number') {
data = Number(result.data).toString()
}
return res.send(data)
}
} catch (error) {
logger.error(requestId, 'failed to invoke error', error)
Expand Down
5 changes: 2 additions & 3 deletions packages/app-service/src/router/function/invoke.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* @Author: Maslow<wangfugen@126.com>
* @Date: 2021-07-30 10:30:29
* @LastEditTime: 2021-09-15 15:03:28
* @LastEditTime: 2021-11-03 18:02:23
* @Description:
*/

Expand Down Expand Up @@ -56,12 +56,11 @@ export async function handleInvokeFunction(req: Request, res: Response) {
if (Config.ENABLE_CLOUD_FUNCTION_LOG === 'always') {
await addFunctionLog({
requestId: requestId,
method: req.method,
func_id: func.id,
func_name: func_name,
logs: result.logs,
time_usage: result.time_usage,
created_at: Date.now(),
updated_at: Date.now(),
created_by: req['auth']?.uid,
data: result.data,
error: result.error,
Expand Down
21 changes: 9 additions & 12 deletions packages/cloud-function/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cloud-function/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"url": "https://github.com/Maslow/less-framework/issues"
},
"dependencies": {
"moment": "^2.29.1"
"dayjs": "^1.10.7"
},
"devDependencies": {
"@types/express": "^4.17.11",
Expand Down
6 changes: 3 additions & 3 deletions packages/cloud-function/src/console.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as util from 'util'
import * as moment from 'moment'
import * as dayjs from 'dayjs'

export class FunctionConsole {
private _logs: any[] = []
Expand All @@ -9,13 +9,13 @@ export class FunctionConsole {
}

log(...params: any[]) {
const date = moment().format("YYYY/MM/DD HH:mm:ss")
const date = dayjs().format("YYYY/MM/DD HH:mm:ss")
const r = util.format("[%s] -", date, ...params)
this._logs.push(r)
}

error(...params: any[]) {
const date = moment().format("YYYY/MM/DD HH:mm:ss")
const date = dayjs().format("YYYY/MM/DD HH:mm:ss")
const r = util.format("[%s] -", date, ...params)
this._logs.push(r)
}
Expand Down
2 changes: 0 additions & 2 deletions packages/cloud-function/src/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ export class FunctionEngine {
*/
async run(code: string, context: FunctionContext): Promise<FunctionResult> {
const sandbox = this.buildSandbox(context)


const wrapped = this.wrap(code)
const fconsole = sandbox.console

Expand Down
13 changes: 6 additions & 7 deletions packages/cloud-function/src/trigger-scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export class TriggerScheduler {
this._triggers.push(trigger)
} else {
// 若为定时器,则保留其 `最近一次执行时间`
if(trigger.isTimer) {
if (trigger.isTimer) {
trigger.last_exec_time = this._triggers[index].last_exec_time ?? 0
}

this._triggers[index] = trigger
}

Expand Down Expand Up @@ -86,7 +86,7 @@ export class TriggerScheduler {
* @param func_id 函数ID
* @returns
*/
protected async getFunctionById(_func_id: string): Promise<CloudFunction>{
protected async getFunctionById(_func_id: string): Promise<CloudFunction> {
throw new Error('not implemented, you should drive TriggerScheduler class and override getFunctionById() method')
}

Expand All @@ -104,12 +104,11 @@ export class TriggerScheduler {
result.logs.unshift(`invoked by trigger: ${trigger.name} (${trigger.id})`)
await this.addFunctionLog({
requestId: `trigger_${trigger.id}`,
method: param.method,
func_id: func.id,
func_name: func.name,
logs: result.logs,
time_usage: result.time_usage,
created_at: Date.now(),
updated_at: Date.now(),
created_by: `trigger_${trigger.id}`,
trigger_id: trigger.id
})
Expand All @@ -136,7 +135,7 @@ export class TriggerScheduler {
/**
* 开始调度定时触发器
*/
protected scheduleTimer() {
protected scheduleTimer() {
this.cancelTimer()
this._timer = setInterval(this.timerLoop.bind(this), 1000)
}
Expand All @@ -163,7 +162,7 @@ export class TriggerScheduler {
* @param triggerId
* @returns
*/
protected removeTrigger(triggerId: string): boolean {
protected removeTrigger(triggerId: string): boolean {
const index = this._triggers.findIndex(t => t.id === triggerId)
if (index === -1) {
return false
Expand Down
2 changes: 1 addition & 1 deletion packages/cloud-function/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface FunctionContext {
export interface FunctionResult {
data?: any,
logs: any[],
error?: any,
error?: Error,
time_usage: number
}

Expand Down
Loading

0 comments on commit fa82cb4

Please sign in to comment.