Skip to content

Commit 29f2d22

Browse files
authored
Merge pull request #29 from martin-krcmar/three-queueus
Three queueus
2 parents 8ff45c0 + 5ab32f0 commit 29f2d22

File tree

4 files changed

+146
-5
lines changed

4 files changed

+146
-5
lines changed

appmixer-lib.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
object: require('./util/object'),
1313
component: require('./util/component'),
1414
flow: require('./util/flow'),
15-
PagingAggregator: require('./util/paging-aggregator')
15+
PagingAggregator: require('./util/paging-aggregator'),
16+
promise: require('./util/promise')
1617
}
1718
};

util/component.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'use strict'
1+
'use strict';
22

33
const metrohash128 = require('metrohash').metrohash128;
44
const objectUtil = require('./object');

util/flow.js

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
'use strict'
1+
'use strict';
22

33
/**
44
* Returns generator, which loops over unique input links
@@ -43,9 +43,54 @@ function* allInputLinks(source, checkUniqueIdPort = true) {
4343
}
4444
}
4545

46+
/**
47+
* Returns generator, which loops over all output links from a component's output port.
48+
* @param {Flow} flow
49+
* @param {string} cid - component Id
50+
* @param {string} outputPort
51+
* @return {Iterator<*>}
52+
*/
53+
function* allOutputLinks(flow, cid, outputPort) {
54+
55+
const descriptor = flow.getFlowDescriptor();
56+
for (let componentId in descriptor) {
57+
if (!descriptor.hasOwnProperty(componentId)) {
58+
continue;
59+
}
60+
61+
let source = descriptor[componentId].source;
62+
for (let inputPort in source) {
63+
if (!source.hasOwnProperty(inputPort)) {
64+
continue;
65+
}
66+
67+
let sourceInput = source[inputPort];
68+
for (let sourceComponentId in sourceInput) {
69+
if (!sourceInput.hasOwnProperty(sourceComponentId)) {
70+
continue;
71+
}
72+
73+
if (sourceComponentId !== cid) {
74+
continue;
75+
}
76+
77+
const ports = Array.isArray(sourceInput[sourceComponentId]) ?
78+
sourceInput[sourceComponentId] : [sourceInput[sourceComponentId]];
79+
80+
if (ports.indexOf(outputPort) !== -1) {
81+
yield {
82+
componentId,
83+
inputPort
84+
};
85+
}
86+
}
87+
}
88+
}
89+
}
4690

4791
module.exports = {
4892
ComponentDescriptor: {
49-
allInputLinks
50-
}
93+
allInputLinks,
94+
allOutputLinks
95+
}
5196
};

util/promise.js

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'use strict';
2+
const Promise = require('bluebird');
3+
const check = require('check-types');
4+
5+
/**
6+
* This is a variation of classic Promise.all function. Where Promise.all is fail fast -
7+
* when the first promise fails, the rest is not executed.
8+
* In this case all promises are executed and result array is returned.
9+
* @param {Array} promises
10+
* @return {Promise<*>}
11+
* @throws Error
12+
*/
13+
module.exports.allNoErr = async promises => {
14+
15+
if (!Array.isArray(promises)) {
16+
throw new Error('Promises is not an array.');
17+
}
18+
return Promise.all(promises.map(promise => promise.catch(e => e)));
19+
};
20+
21+
/**
22+
* Similar to the previous function. But in this case when one of the promises fail error
23+
* is thrown. The first error found will be throws. So it's like classic Promise.all but
24+
* all promises are finished.
25+
* @param {Array} promises
26+
* @return {Promise<*>}
27+
* @throws Error
28+
*/
29+
module.exports.all = async promises => {
30+
31+
if (!Array.isArray(promises)) {
32+
throw new Error('Promises is not an array.');
33+
}
34+
return Promise.all(promises.map(promise => promise.catch(e => e)))
35+
.then(results => {
36+
for (let result of results) {
37+
if (result instanceof Error) {
38+
throw result;
39+
}
40+
}
41+
return results;
42+
});
43+
};
44+
45+
/**
46+
* Like Promise.map but again - let all promises finish and then throw an error if one of
47+
* the promises failed. Return result of each promise in an array otherwise.
48+
* @param {Object} object
49+
* @param {function} callback
50+
* @return {Promise<Array>}
51+
* @throws Error
52+
*/
53+
module.exports.mapKeys = async (object, callback) => {
54+
55+
check.assert.object(object, 'Invalid object.');
56+
check.assert.function(callback, 'Invalid callback function');
57+
58+
let results = [];
59+
return Promise.map(Object.keys(object), async key => {
60+
return Promise.resolve(callback(key)).reflect();
61+
}).each(inspection => {
62+
if (!inspection.isFulfilled()) {
63+
throw inspection.reason();
64+
}
65+
results.push(inspection.value());
66+
}).then(() => {
67+
return results;
68+
});
69+
};
70+
71+
/**
72+
* Like Promise.map but again - let all promises finish and then throw an error if one of
73+
* the promises failed. Return result of each promise in an array otherwise.
74+
* @param {Object} object
75+
* @param {function} callback
76+
* @return {Promise<Array>}
77+
* @throws Error
78+
*/
79+
module.exports.mapProperties = async (object, callback) => {
80+
81+
check.assert.object(object, 'Invalid object.');
82+
check.assert.function(callback, 'Invalid callback function');
83+
84+
let results = [];
85+
return Promise.map(Object.keys(object), async key => {
86+
return Promise.resolve(callback(object[key])).reflect();
87+
}).each(inspection => {
88+
if (!inspection.isFulfilled()) {
89+
throw inspection.reason();
90+
}
91+
results.push(inspection.value());
92+
}).then(() => {
93+
return results;
94+
});
95+
};

0 commit comments

Comments
 (0)