修正了取missed rows的框架级逻辑

This commit is contained in:
Xu Chang 2023-04-14 11:44:39 +08:00
parent 358ffb4114
commit 8301bd8606
5 changed files with 86 additions and 81 deletions

View File

@ -47,6 +47,7 @@ var Cache = /** @class */ (function (_super) {
return [4 /*yield*/, this.aspectWrapper.exec(name, params)];
case 1:
_a = _b.sent(), result = _a.result, opRecords = _a.opRecords, message = _a.message;
this.refreshing = false;
callback && callback(result, opRecords);
if (opRecords) {
this.sync(opRecords);
@ -85,7 +86,6 @@ var Cache = /** @class */ (function (_super) {
}, callback)];
case 1:
_a = (_b.sent()).result, ids = _a.ids, count = _a.count;
this.refreshing = false;
selection2 = Object.assign({}, selection, {
filter: {
id: {
@ -133,7 +133,6 @@ var Cache = /** @class */ (function (_super) {
}, callback)];
case 1:
result = _a.sent();
this.refreshing = false;
return [2 /*return*/, result];
}
});
@ -245,6 +244,7 @@ var Cache = /** @class */ (function (_super) {
if (err instanceof Exception_1.OakRowUnexistedException) {
if (!this.refreshing && !allowMiss) {
var missedRows_1 = err.getRows();
this.refreshing = true;
this.exec('fetchRows', missedRows_1, function (result, opRecords) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
var _a, _b, record, d, missedRows_2, missedRows_2_1, mr;
var e_3, _c, e_4, _d;

View File

@ -94,7 +94,7 @@ declare class ListNode<ED extends EntityDict & BaseEntityDict, T extends keyof E
addNamedSorter(sorter: NamedSorterItem<ED, T>, refresh?: boolean): void;
removeNamedSorter(sorter: NamedSorterItem<ED, T>, refresh?: boolean): void;
removeNamedSorterByName(name: string, refresh: boolean): void;
getFreshValue(context: FrontCxt, allowMiss?: boolean): Array<Partial<ED[T]['Schema']>>;
getFreshValue(context: FrontCxt): Array<Partial<ED[T]['Schema']>>;
addItem(item: Omit<ED[T]['CreateSingle']['data'], 'id'>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): void;
removeItem(id: string, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): void;
recoverItem(id: string): void;
@ -149,7 +149,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
};
addChild(path: string, node: SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD>): void;
removeChild(path: string): void;
getFreshValue(context?: FrontCxt, allowMiss?: boolean): Partial<ED[T]['Schema']> | undefined;
getFreshValue(context?: FrontCxt): Partial<ED[T]['Schema']> | undefined;
doBeforeTrigger(): Promise<void>;
doAfterTrigger(): Promise<void>;
create(data: Partial<Omit<ED[T]['CreateSingle']['data'], 'id'>>, beforeExecute?: () => Promise<void>, afterExecute?: () => Promise<void>): void;
@ -174,6 +174,7 @@ declare class SingleNode<ED extends EntityDict & BaseEntityDict, T extends keyof
declare class VirtualNode<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>, AD extends CommonAspectDict<ED, Cxt>> extends Feature {
private dirty;
private executing;
private loading;
private children;
constructor(path?: string, parent?: VirtualNode<ED, Cxt, FrontCxt, AD>);
getActiveModies(child: any): undefined;
@ -219,7 +220,6 @@ export declare class RunningTree<ED extends EntityDict & BaseEntityDict, Cxt ext
private schema;
private authDict;
private root;
private refreshing;
constructor(cache: Cache<ED, Cxt, FrontCxt, AD>, schema: StorageSchema<ED>, authDict: AuthDefDict<ED>);
createNode<T extends keyof ED>(options: CreateNodeOptions<ED, T>): SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD> | VirtualNode<ED, Cxt, FrontCxt, AD>;
private findNode;

View File

@ -199,7 +199,7 @@ var Node = /** @class */ (function (_super) {
return !!this.dirty;
};
Node.prototype.isLoading = function () {
return this.loading;
return this.loading || (!!this.parent && this.parent.isLoading());
};
Node.prototype.setLoading = function (loading) {
this.loading = loading;
@ -568,7 +568,7 @@ var ListNode = /** @class */ (function (_super) {
this.publish();
}
};
ListNode.prototype.getFreshValue = function (context, allowMiss) {
ListNode.prototype.getFreshValue = function (context) {
var _this = this;
/**
* 满足当前结点的数据应当是所有满足当前filter条件且ids在当前ids中的数据
@ -579,7 +579,7 @@ var ListNode = /** @class */ (function (_super) {
data: data,
filter: filter,
sorter: sorter,
}, context, allowMiss);
}, context, this.isLoading());
return result.filter(function (ele) { var _a; return ele.$$createAt$$ === 1 || ((_a = _this.ids) === null || _a === void 0 ? void 0 : _a.includes(ele.id)); });
};
ListNode.prototype.addItem = function (item, beforeExecute, afterExecute) {
@ -966,12 +966,14 @@ var ListNode = /** @class */ (function (_super) {
this.refresh(currentPage, undefined, append);
};
ListNode.prototype.clean = function () {
this.dirty = undefined;
this.updates = {};
for (var k in this.children) {
this.children[k].clean();
if (this.dirty) {
this.dirty = undefined;
this.updates = {};
for (var k in this.children) {
this.children[k].clean();
}
this.publish();
}
this.publish();
};
ListNode.prototype.getChildOperation = function (child) {
var childId = '';
@ -1075,7 +1077,7 @@ var SingleNode = /** @class */ (function (_super) {
SingleNode.prototype.removeChild = function (path) {
(0, lodash_1.unset)(this.children, path);
};
SingleNode.prototype.getFreshValue = function (context, allowMiss) {
SingleNode.prototype.getFreshValue = function (context) {
var projection = this.getProjection(context, false);
var id = this.id;
if (projection) {
@ -1084,7 +1086,7 @@ var SingleNode = /** @class */ (function (_super) {
filter: {
id: id,
},
}, context, allowMiss);
}, context, this.isLoading());
return result[0];
}
};
@ -1376,12 +1378,14 @@ var SingleNode = /** @class */ (function (_super) {
});
};
SingleNode.prototype.clean = function () {
this.dirty = undefined;
this.operation = undefined;
for (var child in this.children) {
this.children[child].clean();
if (this.dirty) {
this.dirty = undefined;
this.operation = undefined;
for (var child in this.children) {
this.children[child].clean();
}
this.publish();
}
this.publish();
};
SingleNode.prototype.getFilter = function () {
return {
@ -1509,6 +1513,7 @@ var VirtualNode = /** @class */ (function (_super) {
tslib_1.__extends(VirtualNode, _super);
function VirtualNode(path, parent) {
var _this = _super.call(this) || this;
_this.loading = false;
_this.dirty = false;
_this.executing = false;
_this.children = {};
@ -1562,14 +1567,26 @@ var VirtualNode = /** @class */ (function (_super) {
};
VirtualNode.prototype.refresh = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var err_3;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, Promise.all(Object.keys(this.children).map(function (ele) { return _this.children[ele].refresh(); }))];
case 0:
this.loading = true;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, Promise.all(Object.keys(this.children).map(function (ele) { return _this.children[ele].refresh(); }))];
case 2:
_a.sent();
this.loading = false;
this.publish();
return [2 /*return*/];
return [3 /*break*/, 4];
case 3:
err_3 = _a.sent();
this.loading = false;
throw err_3;
case 4: return [2 /*return*/];
}
});
});
@ -1613,12 +1630,7 @@ var VirtualNode = /** @class */ (function (_super) {
return this.executing;
};
VirtualNode.prototype.isLoading = function () {
for (var ele in this.children) {
if (this.children[ele].isLoading()) {
return true;
}
}
return false;
return this.loading;
};
VirtualNode.prototype.doBeforeTrigger = function () {
return tslib_1.__awaiter(this, void 0, void 0, function () {
@ -1704,7 +1716,6 @@ var RunningTree = /** @class */ (function (_super) {
tslib_1.__extends(RunningTree, _super);
function RunningTree(cache, schema, authDict) {
var _this = _super.call(this) || this;
_this.refreshing = false;
// this.aspectWrapper = aspectWrapper;
_this.cache = cache;
_this.schema = schema;
@ -1832,7 +1843,7 @@ var RunningTree = /** @class */ (function (_super) {
if (opers) {
this.cache.redoOperation(opers, context_1);
}
var value = node.getFreshValue(context_1, this.refreshing);
var value = node.getFreshValue(context_1);
context_1.rollback();
return value;
}
@ -1901,7 +1912,6 @@ var RunningTree = /** @class */ (function (_super) {
switch (_a.label) {
case 0:
node = this.findNode(path);
this.refreshing = true;
if (!(node instanceof ListNode)) return [3 /*break*/, 2];
return [4 /*yield*/, node.refresh(1, true)];
case 1:
@ -1913,9 +1923,7 @@ var RunningTree = /** @class */ (function (_super) {
case 3:
_a.sent();
_a.label = 4;
case 4:
this.refreshing = false;
return [2 /*return*/];
case 4: return [2 /*return*/];
}
});
});
@ -1927,12 +1935,10 @@ var RunningTree = /** @class */ (function (_super) {
switch (_a.label) {
case 0:
node = this.findNode(path);
this.refreshing = true;
(0, assert_1.assert)(node instanceof ListNode);
return [4 /*yield*/, node.loadMore()];
case 1:
_a.sent();
this.refreshing = false;
return [2 /*return*/];
}
});
@ -2061,7 +2067,7 @@ var RunningTree = /** @class */ (function (_super) {
};
RunningTree.prototype.execute = function (path, action) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var node, operations, entities, result, err_3;
var node, operations, entities, result, err_4;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
@ -2086,7 +2092,6 @@ var RunningTree = /** @class */ (function (_super) {
operations = node.composeOperations();
entities = (0, lodash_1.uniq)(operations.filter(function (ele) { return !!ele; }).map(function (ele) { return ele.entity; }));
(0, assert_1.assert)(entities.length === 1);
this.refreshing = true;
return [4 /*yield*/, this.cache.operate(entities[0], operations
.filter(function (ele) { return !!ele; })
.map(function (ele) { return ele.operation; }), undefined, function () {
@ -2096,15 +2101,14 @@ var RunningTree = /** @class */ (function (_super) {
})];
case 3:
result = _a.sent();
this.refreshing = false;
return [4 /*yield*/, node.doAfterTrigger()];
case 4:
_a.sent();
return [2 /*return*/, result];
case 5:
err_3 = _a.sent();
err_4 = _a.sent();
node.setExecuting(false);
throw err_3;
throw err_4;
case 6: return [2 /*return*/];
}
});

View File

@ -66,6 +66,7 @@ export class Cache<
) {
try {
const { result, opRecords, message } = await this.aspectWrapper.exec(name, params);
this.refreshing = false;
callback && callback(result, opRecords);
if (opRecords) {
this.sync(opRecords);
@ -101,7 +102,6 @@ export class Cache<
option,
getCount,
}, callback);
this.refreshing = false;
const selection2 = Object.assign({}, selection, {
filter: {
@ -143,7 +143,6 @@ export class Cache<
operation,
option,
}, callback);
this.refreshing = false;
return result;
}
@ -255,6 +254,7 @@ export class Cache<
if (err instanceof OakRowUnexistedException) {
if (!this.refreshing && !allowMiss) {
const missedRows = err.getRows();
this.refreshing = true;
this.exec('fetchRows', missedRows, async (result, opRecords) => {
// missedRows理论上一定要取到不能为空集。否则就是程序员有遗漏
for (const record of opRecords!) {

View File

@ -268,8 +268,8 @@ abstract class Node<
return !!this.dirty;
}
isLoading() {
return this.loading;
isLoading(): boolean {
return this.loading || (!!this.parent && this.parent.isLoading());
}
protected setLoading(loading: boolean) {
@ -691,7 +691,7 @@ class ListNode<
}
}
getFreshValue(context: FrontCxt, allowMiss?: boolean): Array<Partial<ED[T]['Schema']>> {
getFreshValue(context: FrontCxt): Array<Partial<ED[T]['Schema']>> {
/**
* filter条件且ids在当前ids中的数据
* create的行则例外create的数据
@ -702,7 +702,7 @@ class ListNode<
data,
filter,
sorter,
}, context, allowMiss);
}, context, this.isLoading());
return result.filter(
ele => ele.$$createAt$$ === 1 || this.ids?.includes(ele.id!)
);
@ -1043,13 +1043,15 @@ class ListNode<
}
clean() {
this.dirty = undefined;
this.updates = {};
for (const k in this.children) {
this.children[k].clean();
if (this.dirty) {
this.dirty = undefined;
this.updates = {};
for (const k in this.children) {
this.children[k].clean();
}
this.publish();
}
this.publish();
}
getChildOperation(child: SingleNode<ED, T, Cxt, FrontCxt, AD>) {
@ -1188,7 +1190,7 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
unset(this.children, path);
}
getFreshValue(context?: FrontCxt, allowMiss?: boolean): Partial<ED[T]['Schema']> | undefined {
getFreshValue(context?: FrontCxt): Partial<ED[T]['Schema']> | undefined {
const projection = this.getProjection(context, false);
const { id } = this;
if (projection) {
@ -1197,7 +1199,7 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
filter: {
id,
},
}, context, allowMiss);
}, context, this.isLoading());
return result[0];
}
}
@ -1444,13 +1446,15 @@ class SingleNode<ED extends EntityDict & BaseEntityDict,
}
clean() {
this.dirty = undefined;
this.operation = undefined;
for (const child in this.children) {
this.children[child]!.clean();
if (this.dirty) {
this.dirty = undefined;
this.operation = undefined;
for (const child in this.children) {
this.children[child]!.clean();
}
this.publish();
}
this.publish();
}
getFilter(): ED[T]['Selection']['filter'] | undefined {
@ -1584,6 +1588,7 @@ class VirtualNode<
> extends Feature {
private dirty: boolean;
private executing: boolean;
private loading = false;
private children: Record<string, SingleNode<ED, keyof ED, Cxt, FrontCxt, AD> | ListNode<ED, keyof ED, Cxt, FrontCxt, AD> | VirtualNode<ED, Cxt, FrontCxt, AD>>;
constructor(path?: string, parent?: VirtualNode<ED, Cxt, FrontCxt, AD>) {
super();
@ -1641,12 +1646,20 @@ class VirtualNode<
return this.dirty;
}
async refresh() {
await Promise.all(
Object.keys(this.children).map(
ele => this.children[ele].refresh()
)
);
this.publish();
this.loading = true;
try {
await Promise.all(
Object.keys(this.children).map(
ele => this.children[ele].refresh()
)
);
this.loading = false;
this.publish();
}
catch (err) {
this.loading = false;
throw err;
}
}
composeOperations(): Array<{ entity: keyof ED, operation: ED[keyof ED]['Operation'] }> | undefined {
/**
@ -1691,12 +1704,7 @@ class VirtualNode<
}
isLoading() {
for (const ele in this.children) {
if (this.children[ele].isLoading()) {
return true;
}
}
return false;
return this.loading;
}
async doBeforeTrigger() {
@ -1772,7 +1780,6 @@ export class RunningTree<
| ListNode<ED, keyof ED, Cxt, FrontCxt, AD>
| VirtualNode<ED, Cxt, FrontCxt, AD>
>;
private refreshing = false;
constructor(
cache: Cache<ED, Cxt, FrontCxt, AD>,
@ -1945,7 +1952,7 @@ export class RunningTree<
if (opers) {
this.cache.redoOperation(opers, context);
}
const value = node.getFreshValue(context, this.refreshing);
const value = node.getFreshValue(context);
context.rollback();
return value;
}
@ -2056,21 +2063,17 @@ export class RunningTree<
async refresh(path: string) {
const node = this.findNode(path);
this.refreshing = true;
if (node instanceof ListNode) {
await node.refresh(1, true);
} else if (node) {
await node.refresh();
}
this.refreshing = false;
}
async loadMore(path: string) {
const node = this.findNode(path);
this.refreshing = true;
assert(node instanceof ListNode);
await node.loadMore();
this.refreshing = false;
}
getPagination(path: string) {
@ -2262,7 +2265,6 @@ export class RunningTree<
);
assert(entities.length === 1);
this.refreshing = true;
const result = await this.cache.operate(
entities[0],
operations
@ -2275,7 +2277,6 @@ export class RunningTree<
node.setExecuting(false);
}
);
this.refreshing = false;
await node.doAfterTrigger();