state-trooper
Version:
Application State Manager
112 lines (92 loc) • 2.2 kB
JavaScript
;
var csp = require('./csp.core');
function pipelineInternal(n, to, from, close, taskFn) {
if (n <= 0) {
throw new Error('n must be positive');
}
var jobs = csp.chan(n);
var results = csp.chan(n);
for(var _ = 0; _ < n; _++) {
csp.go(function* (taskFn, jobs, results) {
while (true) {
var job = yield csp.take(jobs);
if (!taskFn(job)) {
results.close();
break;
}
}
}, [taskFn, jobs, results]);
}
csp.go(function* (jobs, from, results) {
while (true) {
var v = yield csp.take(from);
if (v === csp.CLOSED) {
jobs.close();
break;
} else {
var p = csp.chan(1);
yield csp.put(jobs, [v, p]);
yield csp.put(results, p);
}
}
}, [jobs, from, results]);
csp.go(function* (results, close, to) {
while(true) {
var p = yield csp.take(results);
if (p === csp.CLOSED) {
if (close) {
to.close();
}
break;
} else {
var res = yield csp.take(p);
while(true) {
var v = yield csp.take(res);
if (v !== csp.CLOSED) {
yield csp.put(to, v);
} else {
break;
}
}
}
}
}, [results, close, to]);
return to;
}
function pipeline(to, xf, from, keepOpen, exHandler) {
function taskFn(job) {
if (job === csp.CLOSED) {
return null;
} else {
var v = job[0];
var p = job[1];
var res = csp.chan(1, xf, exHandler);
csp.go(function* (res, v) {
yield csp.put(res, v);
res.close();
}, [res, v]);
csp.putAsync(p, res);
return true;
}
}
return pipelineInternal(1, to, from, !keepOpen, taskFn);
}
function pipelineAsync(n, to, af, from, keepOpen) {
function taskFn(job) {
if (job === csp.CLOSED) {
return null;
} else {
var v = job[0];
var p = job[1];
var res = csp.chan(1);
af(v, res);
csp.putAsync(p, res);
return true;
}
}
return pipelineInternal(n, to, from, !keepOpen, taskFn);
}
module.exports = {
pipeline: pipeline,
pipelineAsync: pipelineAsync
};