midway-fatcms 0.0.1-beta.73 → 0.0.1-beta.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -162,7 +162,13 @@ exports.default = (appInfo) => {
162
162
  // 用户会话保持时间,单位秒
163
163
  fatcmsUserSessionKeepTimeSecond: 3600 * 24 * 30,
164
164
  // 是否启用内置的定时任务
165
- fatcmsScheduleService: true,
165
+ fatcmsScheduleService: {
166
+ proxyApiLoadService: 2 * 60 * 1000,
167
+ workbenchService: 60 * 1000,
168
+ visitStatService: 10 * 60 * 1000,
169
+ asyncTaskRunnerService: 1000,
170
+ cacheServiceFactory: 2 * 60 * 1000, // 2分钟重新加载一次,
171
+ },
166
172
  // Excel导出文件的临时目录
167
173
  fatcmsExportExcelTmpFilePath: (0, path_1.join)((0, os_1.tmpdir)(), 'fatcms-export-excel'),
168
174
  // 在某些场景下,只有一个workbench code。如果启用了此配置,则不再根据域名配置识别Workbench.
package/dist/index.d.ts CHANGED
@@ -73,6 +73,7 @@ export * from './service/proxyapi/ProxyApiLoadService';
73
73
  export * from './service/proxyapi/ProxyApiService';
74
74
  export * from './service/asyncTask/AsyncTaskService';
75
75
  export * from './service/asyncTask/AsyncTaskRunnerService';
76
+ export * from './schedule/anonymousContext';
76
77
  export * from './models/userSession';
77
78
  export * from './models/bizmodels';
78
79
  export * from './models/SystemEntities';
package/dist/index.js CHANGED
@@ -91,6 +91,7 @@ __exportStar(require("./service/proxyapi/ProxyApiLoadService"), exports);
91
91
  __exportStar(require("./service/proxyapi/ProxyApiService"), exports);
92
92
  __exportStar(require("./service/asyncTask/AsyncTaskService"), exports);
93
93
  __exportStar(require("./service/asyncTask/AsyncTaskRunnerService"), exports);
94
+ __exportStar(require("./schedule/anonymousContext"), exports);
94
95
  __exportStar(require("./models/userSession"), exports);
95
96
  __exportStar(require("./models/bizmodels"), exports);
96
97
  __exportStar(require("./models/SystemEntities"), exports);
@@ -8,6 +8,7 @@ declare class AnonymousContext {
8
8
  private app;
9
9
  setApp(app: koa.Application): void;
10
10
  getApp(): koa.IMidwayKoaApplication;
11
+ private createAnonymousContext;
11
12
  runServiceAtAnonymousContext(runner: RunServiceAtAnonymousContextRunner): Promise<RunServiceAtAnonymousContextRes>;
12
13
  }
13
14
  declare const ANONYMOUS_CONTEXT: AnonymousContext;
@@ -4,6 +4,7 @@ exports.ANONYMOUS_CONTEXT = void 0;
4
4
  const contextLogger_1 = require("../models/contextLogger");
5
5
  const Transaction_1 = require("../libs/crud-pro/models/Transaction");
6
6
  const userSession_1 = require("../models/userSession");
7
+ const WorkbenchInfoTools_1 = require("../models/WorkbenchInfoTools");
7
8
  const anonymousUserInfo = {
8
9
  nickName: 'anonymous_user',
9
10
  avatar: '',
@@ -35,7 +36,12 @@ class AnonymousContext {
35
36
  getApp() {
36
37
  return this.app;
37
38
  }
38
- async runServiceAtAnonymousContext(runner) {
39
+ //
40
+ // async getAsyncService(identifier: any): Promise<any> {
41
+ // const ctx: koa.IMidwayKoaContext = this.createAnonymousContext();
42
+ // return ctx.requestContext.getAsync(identifier);
43
+ // }
44
+ createAnonymousContext() {
39
45
  const app = this.app;
40
46
  const ctx = app.createAnonymousContext();
41
47
  ctx.app = app;
@@ -43,6 +49,11 @@ class AnonymousContext {
43
49
  ctx.transaction = new Transaction_1.Transaction();
44
50
  ctx.userSession = new userSession_1.UserSessionInfo(anonymousUserInfo, true);
45
51
  ctx.workbenchInfo = anonymousWorkbenchInfo;
52
+ ctx.workbenchInfoTools = new WorkbenchInfoTools_1.WorkbenchInfoTools(ctx.workbenchInfo);
53
+ return ctx;
54
+ }
55
+ async runServiceAtAnonymousContext(runner) {
56
+ const ctx = this.createAnonymousContext();
46
57
  let result = null;
47
58
  let error = null;
48
59
  try {
@@ -3,11 +3,13 @@ declare const INNER_SCHEDULE_INTERVAL: {
3
3
  workbenchService: number;
4
4
  visitStatService: number;
5
5
  asyncTaskRunnerService: number;
6
+ cacheServiceFactory: number;
6
7
  };
7
8
  declare const INNER_SCHEDULE_NAMES: {
8
9
  proxyApiLoadService: string;
9
10
  workbenchService: string;
10
11
  visitStatService: string;
11
12
  asyncTaskRunnerService: string;
13
+ cacheServiceFactory: string;
12
14
  };
13
15
  export { INNER_SCHEDULE_INTERVAL, INNER_SCHEDULE_NAMES };
@@ -5,7 +5,8 @@ const INNER_SCHEDULE_INTERVAL = {
5
5
  proxyApiLoadService: 2 * 60 * 1000,
6
6
  workbenchService: 60 * 1000,
7
7
  visitStatService: 10 * 60 * 1000,
8
- asyncTaskRunnerService: 1000, // 1s可以执行
8
+ asyncTaskRunnerService: 1000,
9
+ cacheServiceFactory: 2 * 60 * 1000, // 2分钟重新加载一次,
9
10
  };
10
11
  exports.INNER_SCHEDULE_INTERVAL = INNER_SCHEDULE_INTERVAL;
11
12
  const INNER_SCHEDULE_NAMES = {
@@ -13,5 +14,6 @@ const INNER_SCHEDULE_NAMES = {
13
14
  workbenchService: 'workbenchService',
14
15
  visitStatService: 'visitStatService',
15
16
  asyncTaskRunnerService: 'asyncTaskRunnerService',
17
+ cacheServiceFactory: 'cacheServiceFactory',
16
18
  };
17
19
  exports.INNER_SCHEDULE_NAMES = INNER_SCHEDULE_NAMES;
@@ -1,20 +1,23 @@
1
1
  import { Context } from '@midwayjs/koa';
2
2
  import { CacheNameEnum, ICacheService } from '../../../models/bizmodels';
3
3
  import { RedisService } from '@midwayjs/redis';
4
+ import { IScheduleService } from "../../../interface";
4
5
  interface IGetJsonObjectCacheParam {
5
6
  cacheName: CacheNameEnum;
6
7
  cacheKey: string;
7
8
  refreshCache?: boolean;
9
+ scheduleRefresh?: boolean;
8
10
  getter: () => Promise<any>;
9
11
  }
10
12
  interface IRemoveItemCacheParam {
11
13
  cacheName: CacheNameEnum;
12
14
  cacheKey: string;
13
15
  }
14
- export declare class CacheServiceFactory {
16
+ export declare class CacheServiceFactory implements IScheduleService {
15
17
  protected ctx: Context;
16
18
  private fatcmsCache;
17
19
  protected redisService: RedisService;
20
+ runBySchedule(): Promise<void>;
18
21
  private getCacheService;
19
22
  getCacheServiceByName(cacheName: CacheNameEnum): ICacheService;
20
23
  getJsonObjectCache(param: IGetJsonObjectCacheParam): Promise<any>;
@@ -22,7 +22,40 @@ const defaultCacheConfig = {
22
22
  cacheLevel: SystemEntities_1.CacheLevelEnum.MEMORY,
23
23
  cacheSecond: 60 * 60 * 24 * 7
24
24
  };
25
+ const isScheduleBusyTag = { busy: false };
26
+ const SCHEDULE_REFRESH_TASK_MAP = new Map;
25
27
  let CacheServiceFactory = class CacheServiceFactory {
28
+ async runBySchedule() {
29
+ if (isScheduleBusyTag.busy) {
30
+ return;
31
+ }
32
+ isScheduleBusyTag.busy = true;
33
+ try {
34
+ const keys = SCHEDULE_REFRESH_TASK_MAP.keys();
35
+ for (const key of keys) {
36
+ const param = SCHEDULE_REFRESH_TASK_MAP.get(key);
37
+ try {
38
+ if (param) {
39
+ const { cacheName, cacheKey, getter } = param;
40
+ const cacheService = this.getCacheServiceByName(cacheName);
41
+ if (cacheService) {
42
+ const obj = await getter();
43
+ await cacheService.setJsonObject(cacheKey, obj);
44
+ }
45
+ }
46
+ }
47
+ catch (error) {
48
+ this.ctx.logger.error(`[CacheServiceFactory]runBySchedule#${param.cacheName}`, error);
49
+ }
50
+ }
51
+ }
52
+ catch (e) {
53
+ this.ctx.logger.error(`[CacheServiceFactory]runBySchedule`, e);
54
+ }
55
+ finally {
56
+ isScheduleBusyTag.busy = false;
57
+ }
58
+ }
26
59
  getCacheService(cacheLevelEnum, cacheName, cacheSecond) {
27
60
  switch (cacheLevelEnum) {
28
61
  case SystemEntities_1.CacheLevelEnum.CONTEXT:
@@ -50,7 +83,13 @@ let CacheServiceFactory = class CacheServiceFactory {
50
83
  return this.getCacheService(cacheLevel, cacheName, cacheSecond);
51
84
  }
52
85
  async getJsonObjectCache(param) {
53
- const { cacheName, cacheKey, refreshCache, getter } = param;
86
+ const { cacheName, cacheKey, refreshCache, scheduleRefresh, getter } = param;
87
+ if (scheduleRefresh === true) {
88
+ const scheduleKey = `${cacheName}_${cacheKey}`;
89
+ if (!SCHEDULE_REFRESH_TASK_MAP.has(scheduleKey)) {
90
+ SCHEDULE_REFRESH_TASK_MAP.set(scheduleKey, param);
91
+ }
92
+ }
54
93
  const cacheService = this.getCacheServiceByName(cacheName);
55
94
  let obj = await cacheService.getJsonObject(cacheKey);
56
95
  if (!obj || refreshCache === true) {
@@ -8,6 +8,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var CurdMixByLinkToCustomService_1;
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
13
  exports.CurdMixByLinkToCustomService = void 0;
13
14
  const core_1 = require("@midwayjs/core");
@@ -22,6 +23,7 @@ const global_config_1 = require("../../libs/global-config/global-config");
22
23
  const bizmodels_1 = require("../../models/bizmodels");
23
24
  const CacheServiceFactory_1 = require("../base/cache/CacheServiceFactory");
24
25
  const md5 = require("md5");
26
+ const schedule_1 = require("../../schedule");
25
27
  const linkToCustomMixUtils = new CurdMixUtils_1.CrudMixUtils(CurdMixUtils_1.RelatedType.linkToCustom);
26
28
  const TMP_CTX_KEY = _.uniqueId('CurdMixByLinkToCustomService');
27
29
  function toMapObject(rows, fieldsArr) {
@@ -47,7 +49,7 @@ function toMapObject(rows, fieldsArr) {
47
49
  }
48
50
  return map;
49
51
  }
50
- let CurdMixByLinkToCustomService = class CurdMixByLinkToCustomService {
52
+ let CurdMixByLinkToCustomService = CurdMixByLinkToCustomService_1 = class CurdMixByLinkToCustomService {
51
53
  async handleExecuteContextPrepare(executeContext) {
52
54
  const relations = linkToCustomMixUtils.pickColumnRelations(executeContext);
53
55
  if (!relations || relations.length === 0) {
@@ -83,8 +85,13 @@ let CurdMixByLinkToCustomService = class CurdMixByLinkToCustomService {
83
85
  return this.cacheServiceFactory.getJsonObjectCache({
84
86
  cacheKey: md5(code),
85
87
  cacheName: bizmodels_1.CacheNameEnum.CurdMixByLinkToCustom,
88
+ scheduleRefresh: true,
86
89
  getter: async () => {
87
- return await this.queryInfoByLinkToCustomImpl(code);
90
+ const { result } = await schedule_1.ANONYMOUS_CONTEXT.runServiceAtAnonymousContext(async (ctx) => {
91
+ const service = await ctx.requestContext.getAsync(CurdMixByLinkToCustomService_1);
92
+ return await service.queryInfoByLinkToCustomImpl(code);
93
+ });
94
+ return result;
88
95
  },
89
96
  });
90
97
  }
@@ -196,7 +203,7 @@ __decorate([
196
203
  (0, core_1.Inject)(),
197
204
  __metadata("design:type", CacheServiceFactory_1.CacheServiceFactory)
198
205
  ], CurdMixByLinkToCustomService.prototype, "cacheServiceFactory", void 0);
199
- CurdMixByLinkToCustomService = __decorate([
206
+ CurdMixByLinkToCustomService = CurdMixByLinkToCustomService_1 = __decorate([
200
207
  (0, core_1.Provide)()
201
208
  ], CurdMixByLinkToCustomService);
202
209
  exports.CurdMixByLinkToCustomService = CurdMixByLinkToCustomService;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midway-fatcms",
3
- "version": "0.0.1-beta.73",
3
+ "version": "0.0.1-beta.75",
4
4
  "description": "This is a midway component sample",
5
5
  "main": "dist/index.js",
6
6
  "typings": "index.d.ts",
@@ -180,7 +180,13 @@ export default (appInfo: any) => {
180
180
  fatcmsUserSessionKeepTimeSecond: 3600 * 24 * 30,
181
181
 
182
182
  // 是否启用内置的定时任务
183
- fatcmsScheduleService: true,
183
+ fatcmsScheduleService: {
184
+ proxyApiLoadService: 2 * 60 * 1000, // 2分钟重新加载一次,
185
+ workbenchService: 60 * 1000, // 1分钟重新加载一次,
186
+ visitStatService: 10 * 60 * 1000, // 10分钟重新加载一次,
187
+ asyncTaskRunnerService: 1000, // 1s可以执行
188
+ cacheServiceFactory: 2 * 60 * 1000, // 2分钟重新加载一次,
189
+ },
184
190
 
185
191
  // Excel导出文件的临时目录
186
192
  fatcmsExportExcelTmpFilePath: join(tmpdir(), 'fatcms-export-excel'),
package/src/index.ts CHANGED
@@ -73,6 +73,7 @@ export * from './service/proxyapi/ProxyApiLoadService';
73
73
  export * from './service/proxyapi/ProxyApiService';
74
74
  export * from './service/asyncTask/AsyncTaskService';
75
75
  export * from './service/asyncTask/AsyncTaskRunnerService';
76
+ export * from './schedule/anonymousContext'
76
77
  export * from './models/userSession';
77
78
  export * from './models/bizmodels';
78
79
  export * from './models/SystemEntities';
@@ -3,6 +3,7 @@ import { ContextLogger } from '@/models/contextLogger';
3
3
  import { Transaction } from '@/libs/crud-pro/models/Transaction';
4
4
  import { ISessionInfo, SYS_ACCOUNT_TYPE, UserSessionInfo } from '@/models/userSession';
5
5
  import { IWorkbenchEntity } from '@/models/SystemEntities';
6
+ import { WorkbenchInfoTools } from "@/models/WorkbenchInfoTools";
6
7
 
7
8
  const anonymousUserInfo: ISessionInfo = {
8
9
  nickName: 'anonymous_user',
@@ -36,6 +37,7 @@ export interface RunServiceAtAnonymousContextRes {
36
37
  error: any;
37
38
  }
38
39
 
40
+
39
41
  class AnonymousContext {
40
42
  private app: koa.Application;
41
43
 
@@ -47,16 +49,27 @@ class AnonymousContext {
47
49
  return this.app;
48
50
  }
49
51
 
50
- async runServiceAtAnonymousContext(runner: RunServiceAtAnonymousContextRunner): Promise<RunServiceAtAnonymousContextRes> {
52
+ //
53
+ // async getAsyncService(identifier: any): Promise<any> {
54
+ // const ctx: koa.IMidwayKoaContext = this.createAnonymousContext();
55
+ // return ctx.requestContext.getAsync(identifier);
56
+ // }
57
+
58
+ private createAnonymousContext() {
51
59
  const app = this.app;
52
60
  const ctx: koa.IMidwayKoaContext = app.createAnonymousContext();
53
-
54
61
  ctx.app = app;
55
62
  ctx.contextLogger = new ContextLogger(ctx as any);
56
63
  ctx.transaction = new Transaction();
57
64
  ctx.userSession = new UserSessionInfo(anonymousUserInfo, true);
58
65
  ctx.workbenchInfo = anonymousWorkbenchInfo;
66
+ ctx.workbenchInfoTools = new WorkbenchInfoTools(ctx.workbenchInfo);
67
+ return ctx;
68
+ }
69
+
59
70
 
71
+ async runServiceAtAnonymousContext(runner: RunServiceAtAnonymousContextRunner): Promise<RunServiceAtAnonymousContextRes> {
72
+ const ctx: koa.IMidwayKoaContext = this.createAnonymousContext();
60
73
  let result: any = null;
61
74
  let error: any = null;
62
75
  try {
@@ -3,6 +3,7 @@ const INNER_SCHEDULE_INTERVAL = {
3
3
  workbenchService: 60 * 1000, // 1分钟重新加载一次,
4
4
  visitStatService: 10 * 60 * 1000, // 10分钟重新加载一次,
5
5
  asyncTaskRunnerService: 1000, // 1s可以执行
6
+ cacheServiceFactory: 2 * 60 * 1000, // 2分钟重新加载一次,
6
7
  };
7
8
 
8
9
  const INNER_SCHEDULE_NAMES = {
@@ -10,6 +11,7 @@ const INNER_SCHEDULE_NAMES = {
10
11
  workbenchService: 'workbenchService',
11
12
  visitStatService: 'visitStatService',
12
13
  asyncTaskRunnerService: 'asyncTaskRunnerService',
14
+ cacheServiceFactory: 'cacheServiceFactory',
13
15
  };
14
16
 
15
17
  export { INNER_SCHEDULE_INTERVAL, INNER_SCHEDULE_NAMES };
@@ -8,11 +8,13 @@ import { RedisCache } from './RedisCache';
8
8
  import { DiskCache } from './DiskCache';
9
9
  import { MemoryCache } from './MemoryCache';
10
10
  import { NoneCache } from './NoneCache';
11
+ import {IScheduleService} from "@/interface";
11
12
 
12
13
  interface IGetJsonObjectCacheParam {
13
14
  cacheName: CacheNameEnum;
14
15
  cacheKey: string;
15
16
  refreshCache?: boolean;
17
+ scheduleRefresh?: boolean;
16
18
  getter: () => Promise<any>;
17
19
  }
18
20
 
@@ -26,8 +28,13 @@ const defaultCacheConfig: IWorkbenchConfigCacheLevel = {
26
28
  cacheSecond: 60 * 60 * 24 * 7
27
29
  }
28
30
 
31
+ const isScheduleBusyTag = { busy : false };
32
+
33
+ const SCHEDULE_REFRESH_TASK_MAP = new Map<string, IGetJsonObjectCacheParam>;
34
+
35
+
29
36
  @Provide()
30
- export class CacheServiceFactory {
37
+ export class CacheServiceFactory implements IScheduleService {
31
38
  @Inject()
32
39
  protected ctx: Context;
33
40
 
@@ -37,6 +44,38 @@ export class CacheServiceFactory {
37
44
  @Inject()
38
45
  protected redisService: RedisService;
39
46
 
47
+ public async runBySchedule() {
48
+
49
+ if (isScheduleBusyTag.busy) {
50
+ return;
51
+ }
52
+ isScheduleBusyTag.busy = true;
53
+
54
+ try {
55
+ const keys = SCHEDULE_REFRESH_TASK_MAP.keys();
56
+ for (const key of keys) {
57
+ const param = SCHEDULE_REFRESH_TASK_MAP.get(key);
58
+ try {
59
+ if (param) {
60
+ const {cacheName, cacheKey, getter} = param;
61
+ const cacheService = this.getCacheServiceByName(cacheName);
62
+ if (cacheService) {
63
+ const obj = await getter();
64
+ await cacheService.setJsonObject(cacheKey, obj);
65
+ }
66
+ }
67
+ } catch (error) {
68
+ this.ctx.logger.error(`[CacheServiceFactory]runBySchedule#${param.cacheName}`, error);
69
+ }
70
+ }
71
+ } catch (e) {
72
+ this.ctx.logger.error(`[CacheServiceFactory]runBySchedule`, e);
73
+ } finally {
74
+ isScheduleBusyTag.busy = false;
75
+ }
76
+
77
+ }
78
+
40
79
  private getCacheService(cacheLevelEnum: CacheLevelEnum, cacheName: CacheNameEnum, cacheSecond: number): ICacheService {
41
80
  switch (cacheLevelEnum) {
42
81
  case CacheLevelEnum.CONTEXT:
@@ -66,8 +105,18 @@ export class CacheServiceFactory {
66
105
  }
67
106
 
68
107
 
108
+
69
109
  public async getJsonObjectCache(param: IGetJsonObjectCacheParam): Promise<any> {
70
- const {cacheName, cacheKey, refreshCache, getter} = param;
110
+ const {cacheName, cacheKey, refreshCache, scheduleRefresh, getter} = param;
111
+
112
+ if (scheduleRefresh === true) {
113
+ const scheduleKey = `${cacheName}_${cacheKey}`;
114
+ if (!SCHEDULE_REFRESH_TASK_MAP.has(scheduleKey)) {
115
+ SCHEDULE_REFRESH_TASK_MAP.set(scheduleKey, param);
116
+ }
117
+ }
118
+
119
+
71
120
  const cacheService = this.getCacheServiceByName(cacheName);
72
121
  let obj = await cacheService.getJsonObject(cacheKey);
73
122
  if (!obj || refreshCache === true) {
@@ -14,6 +14,7 @@ import { IRequestCfgModel2 } from '@/models/bizmodels';
14
14
  import { CacheNameEnum} from "@/models/bizmodels";
15
15
  import { CacheServiceFactory } from '../base/cache/CacheServiceFactory';
16
16
  import * as md5 from 'md5';
17
+ import {ANONYMOUS_CONTEXT} from "@/schedule";
17
18
 
18
19
  const linkToCustomMixUtils = new CrudMixUtils(RelatedType.linkToCustom);
19
20
  const TMP_CTX_KEY = _.uniqueId('CurdMixByLinkToCustomService');
@@ -93,12 +94,18 @@ export class CurdMixByLinkToCustomService implements IExecuteContextHandler {
93
94
  });
94
95
  }
95
96
 
97
+
96
98
  public async queryInfoByLinkToCustom(code: string): Promise<Map<string, any>> {
97
99
  return this.cacheServiceFactory.getJsonObjectCache({
98
100
  cacheKey: md5(code),
99
101
  cacheName: CacheNameEnum.CurdMixByLinkToCustom,
102
+ scheduleRefresh: true,
100
103
  getter: async () => {
101
- return await this.queryInfoByLinkToCustomImpl(code);
104
+ const { result } = await ANONYMOUS_CONTEXT.runServiceAtAnonymousContext(async (ctx: Context) => {
105
+ const service: CurdMixByLinkToCustomService = await ctx.requestContext.getAsync(CurdMixByLinkToCustomService);
106
+ return await service.queryInfoByLinkToCustomImpl(code);
107
+ });
108
+ return result;
102
109
  },
103
110
  });
104
111
  }