270 lines
11 KiB
JavaScript
270 lines
11 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.Cache = void 0;
|
||
var tslib_1 = require("tslib");
|
||
var selection_1 = require("oak-domain/lib/store/selection");
|
||
var Feature_1 = require("../types/Feature");
|
||
var lodash_1 = require("oak-domain/lib/utils/lodash");
|
||
var concurrent_1 = require("oak-domain/lib/utils/concurrent");
|
||
var Exception_1 = require("oak-domain/lib/types/Exception");
|
||
var Cache = /** @class */ (function (_super) {
|
||
tslib_1.__extends(Cache, _super);
|
||
function Cache(aspectWrapper) {
|
||
var _this = _super.call(this, aspectWrapper) || this;
|
||
_this.syncEventsCallbacks = [];
|
||
_this.syncLock = new concurrent_1.RWLock();
|
||
// 在这里把wrapper的返回opRecords截取到并同步到cache中
|
||
var exec = aspectWrapper.exec;
|
||
aspectWrapper.exec = function (name, params) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
||
var _a, result, opRecords;
|
||
return tslib_1.__generator(this, function (_b) {
|
||
switch (_b.label) {
|
||
case 0: return [4 /*yield*/, exec(name, params)];
|
||
case 1:
|
||
_a = _b.sent(), result = _a.result, opRecords = _a.opRecords;
|
||
return [4 /*yield*/, this.sync(opRecords)];
|
||
case 2:
|
||
_b.sent();
|
||
return [2 /*return*/, {
|
||
result: result,
|
||
opRecords: opRecords,
|
||
}];
|
||
}
|
||
});
|
||
}); };
|
||
return _this;
|
||
}
|
||
/**
|
||
* 目前context和cache会形成循环依赖,这里不太好处理,只能先让contextBuilder后注入
|
||
* @param contextBuilder
|
||
*/
|
||
Cache.prototype.init = function (contextBuilder, store) {
|
||
this.contextBuilder = contextBuilder;
|
||
this.cacheStore = store;
|
||
};
|
||
Cache.prototype.refresh = function (entity, selection, option, getCount) {
|
||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||
var result;
|
||
return tslib_1.__generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
(0, selection_1.reinforceSelection)(this.cacheStore.getSchema(), entity, selection);
|
||
return [4 /*yield*/, this.getAspectWrapper().exec('select', {
|
||
entity: entity,
|
||
selection: selection,
|
||
option: option,
|
||
getCount: getCount,
|
||
})];
|
||
case 1:
|
||
result = (_a.sent()).result;
|
||
return [2 /*return*/, result];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
Cache.prototype.operate = function (entity, operation, option) {
|
||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||
var result;
|
||
return tslib_1.__generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0: return [4 /*yield*/, this.getAspectWrapper().exec('operate', {
|
||
entity: entity,
|
||
operation: operation,
|
||
option: option,
|
||
})];
|
||
case 1:
|
||
result = (_a.sent()).result;
|
||
return [2 /*return*/, result];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
Cache.prototype.sync = function (records) {
|
||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||
var context, result;
|
||
return tslib_1.__generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
context = this.contextBuilder();
|
||
return [4 /*yield*/, this.syncLock.acquire('X')];
|
||
case 1:
|
||
_a.sent();
|
||
return [4 /*yield*/, this.cacheStore.sync(records, context)];
|
||
case 2:
|
||
_a.sent();
|
||
this.syncLock.release();
|
||
result = this.syncEventsCallbacks.map(function (ele) { return ele(records); });
|
||
return [4 /*yield*/, Promise.all(result)];
|
||
case 3:
|
||
_a.sent();
|
||
return [2 /*return*/];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
/**
|
||
* 前端缓存做operation只可能是测试权限,必然回滚
|
||
* @param entity
|
||
* @param operation
|
||
* @param scene
|
||
* @param commit
|
||
* @param option
|
||
* @returns
|
||
*/
|
||
Cache.prototype.testOperation = function (entity, operation) {
|
||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||
var context, err_1;
|
||
return tslib_1.__generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
context = this.contextBuilder();
|
||
return [4 /*yield*/, context.begin()];
|
||
case 1:
|
||
_a.sent();
|
||
_a.label = 2;
|
||
case 2:
|
||
_a.trys.push([2, 5, , 7]);
|
||
return [4 /*yield*/, this.cacheStore.operate(entity, operation, context, {
|
||
dontCollect: true,
|
||
dontCreateOper: true,
|
||
})];
|
||
case 3:
|
||
_a.sent();
|
||
return [4 /*yield*/, context.rollback()];
|
||
case 4:
|
||
_a.sent();
|
||
return [3 /*break*/, 7];
|
||
case 5:
|
||
err_1 = _a.sent();
|
||
return [4 /*yield*/, context.rollback()];
|
||
case 6:
|
||
_a.sent();
|
||
throw err_1;
|
||
case 7: return [2 /*return*/, true];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
/**
|
||
* 尝试在cache中重做一些动作,然后选择重做后的数据(为了实现modi)
|
||
* @param entity
|
||
* @param projection
|
||
* @param opers
|
||
*/
|
||
Cache.prototype.tryRedoOperations = function (entity, selection, opers) {
|
||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||
var result, context, opers_1, opers_1_1, oper, e_1_1, err_2, missedRows;
|
||
var e_1, _a;
|
||
return tslib_1.__generator(this, function (_b) {
|
||
switch (_b.label) {
|
||
case 0:
|
||
context = this.contextBuilder();
|
||
return [4 /*yield*/, context.begin()];
|
||
case 1:
|
||
_b.sent();
|
||
_b.label = 2;
|
||
case 2:
|
||
_b.trys.push([2, 7, 8, 9]);
|
||
opers_1 = tslib_1.__values(opers), opers_1_1 = opers_1.next();
|
||
_b.label = 3;
|
||
case 3:
|
||
if (!!opers_1_1.done) return [3 /*break*/, 6];
|
||
oper = opers_1_1.value;
|
||
return [4 /*yield*/, this.cacheStore.operate(oper.entity, oper.operation, context, {
|
||
dontCollect: true,
|
||
dontCreateOper: true,
|
||
blockTrigger: true,
|
||
})];
|
||
case 4:
|
||
_b.sent();
|
||
_b.label = 5;
|
||
case 5:
|
||
opers_1_1 = opers_1.next();
|
||
return [3 /*break*/, 3];
|
||
case 6: return [3 /*break*/, 9];
|
||
case 7:
|
||
e_1_1 = _b.sent();
|
||
e_1 = { error: e_1_1 };
|
||
return [3 /*break*/, 9];
|
||
case 8:
|
||
try {
|
||
if (opers_1_1 && !opers_1_1.done && (_a = opers_1.return)) _a.call(opers_1);
|
||
}
|
||
finally { if (e_1) throw e_1.error; }
|
||
return [7 /*endfinally*/];
|
||
case 9:
|
||
if (!true) return [3 /*break*/, 19];
|
||
_b.label = 10;
|
||
case 10:
|
||
_b.trys.push([10, 13, , 18]);
|
||
return [4 /*yield*/, this.cacheStore.select(entity, selection, context, {
|
||
dontCollect: true,
|
||
})];
|
||
case 11:
|
||
result = _b.sent();
|
||
return [4 /*yield*/, context.rollback()];
|
||
case 12:
|
||
_b.sent();
|
||
return [2 /*return*/, result];
|
||
case 13:
|
||
err_2 = _b.sent();
|
||
if (!(err_2 instanceof Exception_1.OakRowUnexistedException)) return [3 /*break*/, 15];
|
||
missedRows = err_2.getRows();
|
||
return [4 /*yield*/, this.getAspectWrapper().exec('fetchRows', missedRows)];
|
||
case 14:
|
||
_b.sent();
|
||
return [3 /*break*/, 17];
|
||
case 15: return [4 /*yield*/, context.rollback()];
|
||
case 16:
|
||
_b.sent();
|
||
throw err_2;
|
||
case 17: return [3 /*break*/, 18];
|
||
case 18: return [3 /*break*/, 9];
|
||
case 19: return [2 /*return*/];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
Cache.prototype.get = function (entity, selection, params) {
|
||
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
||
var context, result;
|
||
return tslib_1.__generator(this, function (_a) {
|
||
switch (_a.label) {
|
||
case 0:
|
||
context = this.contextBuilder();
|
||
return [4 /*yield*/, this.cacheStore.select(entity, selection, context, {})];
|
||
case 1:
|
||
result = (_a.sent()).result;
|
||
return [2 /*return*/, result];
|
||
}
|
||
});
|
||
});
|
||
};
|
||
Cache.prototype.judgeRelation = function (entity, attr) {
|
||
return this.cacheStore.judgeRelation(entity, attr);
|
||
};
|
||
Cache.prototype.bindOnSync = function (callback) {
|
||
this.syncEventsCallbacks.push(callback);
|
||
};
|
||
Cache.prototype.unbindOnSync = function (callback) {
|
||
(0, lodash_1.pull)(this.syncEventsCallbacks, callback);
|
||
};
|
||
Cache.prototype.getCachedData = function () {
|
||
return this.cacheStore.getCurrentData();
|
||
};
|
||
Cache.prototype.getFullData = function () {
|
||
return this.cacheStore.getFullData();
|
||
};
|
||
Cache.prototype.resetInitialData = function () {
|
||
return this.cacheStore.resetInitialData();
|
||
};
|
||
tslib_1.__decorate([
|
||
Feature_1.Action
|
||
], Cache.prototype, "refresh", null);
|
||
tslib_1.__decorate([
|
||
Feature_1.Action
|
||
], Cache.prototype, "operate", null);
|
||
return Cache;
|
||
}(Feature_1.Feature));
|
||
exports.Cache = Cache;
|