Fixed #303 - Reducer inter-dependency computational rules

This commit is contained in:
Theodor Diaconu 2018-10-23 10:35:12 +03:00
parent 019c50a515
commit a070922c2c
3 changed files with 39 additions and 14 deletions

View file

@ -3,6 +3,7 @@ export default class ReducerNode {
this.name = name;
this.body = body;
this.reduceFunction = reduce;
this.dependencies = []; // This is a list of the reducer this reducer uses.
}
/**

View file

@ -3,9 +3,32 @@ export default function applyReducers(root, params) {
applyReducers(node, params);
});
_.each(root.reducerNodes, reducerNode => {
root.results.forEach(result => {
reducerNode.compute(result, params);
});
});
}
const processedReducers = [];
let reducersQueue = [...root.reducerNodes];
// TODO: find out if there's an infinite reducer inter-deendency
while (reducersQueue.length) {
const reducerNode = reducersQueue.shift();
// If this reducer depends on other reducers
if (reducerNode.dependencies.length) {
// If there is an unprocessed reducer, move it at the end of the queue
const allDependenciesComputed = _.all(reducerNode.dependencies, dep => processedReducers.includes(dep));
if (allDependenciesComputed) {
root.results.forEach(result => {
reducerNode.compute(result, params);
});
processedReducers.push(reducerNode.name);
} else {
// Move it at the end of the queue
reducersQueue.push(reducerNode);
}
} else {
root.results.forEach(result => {
reducerNode.compute(result, params);
});
processedReducers.push(reducerNode.name);
}
}
}

View file

@ -9,7 +9,7 @@ export default function addReducers(root) {
// we add reducers last, after we have added all the fields.
root.reducerNodes.forEach(reducer => {
_.each(reducer.body, (body, fieldName) => {
handleAddElement(root, fieldName, body);
handleAddElement(reducer, root, fieldName, body);
})
});
}
@ -19,7 +19,7 @@ export default function addReducers(root) {
* @param fieldName
* @param body
*/
export function handleAddElement(root, fieldName, body) {
export function handleAddElement(reducerNode, root, fieldName, body) {
// if it's a link
const collection = root.collection;
const linker = collection.getLinker(fieldName);
@ -29,6 +29,7 @@ export function handleAddElement(root, fieldName, body) {
const reducer = collection.getReducer(fieldName);
if (reducer) {
reducerNode.dependencies.push(fieldName);
return handleAddReducer(fieldName, reducer, root);
}
@ -41,14 +42,14 @@ export function handleAddElement(root, fieldName, body) {
* @param reducer
* @param root
*/
export function handleAddReducer(fieldName, reducer, root) {
export function handleAddReducer(fieldName, {body, reduce}, root) {
if (!root.hasReducerNode(fieldName)) {
let reducerNode = new ReducerNode(fieldName, reducer);
root.add(reducerNode);
reducerNode.scheduledForDeletion = true;
let childReducerNode = new ReducerNode(fieldName, {body, reduce});
root.add(childReducerNode);
childReducerNode.scheduledForDeletion = true;
_.each(reducer.body, (body, fieldName) => {
handleAddElement(root, fieldName, body);
_.each(childReducerNode.body, (body, fieldName) => {
handleAddElement(childReducerNode, root, fieldName, body);
})
}
}