10 Commits

Author SHA1 Message Date
7e5c0fe678 2.0.2 2018-08-07 11:13:03 +02:00
93b44ba888 fix(core): update testing framework 2018-08-07 11:13:03 +02:00
30249ad254 2.0.1 2018-08-02 15:35:55 +02:00
07be849d2f fix(package): npm access level 2018-08-02 15:35:55 +02:00
d31f85c6cb 2.0.0 2018-08-02 15:31:06 +02:00
fb2b72a97f BREAKING CHANGE(package): change scope 2018-08-02 15:31:05 +02:00
18dfa70d16 1.0.11 2017-11-28 16:30:04 +01:00
1cb892c357 update ci 2017-11-28 16:30:02 +01:00
275e242ad8 1.0.10 2017-11-28 16:10:19 +01:00
b295b55a92 update to latest standards 2017-11-28 16:10:15 +01:00
43 changed files with 1474 additions and 1013 deletions

View File

@ -1,49 +1,142 @@
image: hosttoday/ht-docker-node:npmts
# gitzone standard
image: hosttoday/ht-docker-node:npmci
cache:
paths:
- .npmci_cache/
key: "$CI_BUILD_STAGE"
stages:
- security
- test
- release
- page
- metadata
# ====================
# security stage
# ====================
mirror:
stage: security
script:
- npmci git mirror
tags:
- docker
- notpriv
snyk:
stage: security
script:
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts
- npmci command snyk test
tags:
- docker
- notpriv
# ====================
# test stage
# ====================
testLEGACY:
stage: test
script:
- npmci test legacy
- npmci node install legacy
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- docker
- notpriv
allow_failure: true
testLTS:
stage: test
script:
- npmci test lts
- npmci node install lts
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- docker
- notpriv
testSTABLE:
stage: test
script:
- npmci test stable
- npmci node install stable
- npmci npm install
- npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- docker
- docker
- notpriv
release:
stage: release
environment: npmjs-com_registry
script:
- npmci publish
- npmci node install stable
- npmci npm publish
only:
- tags
- tags
tags:
- docker
- docker
- notpriv
# ====================
# metadata stage
# ====================
codequality:
stage: metadata
image: docker:stable
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [codeclimate.json]
tags:
- docker
- priv
trigger:
stage: metadata
script:
- npmci trigger
only:
- tags
tags:
- docker
- notpriv
pages:
image: hosttoday/ht-docker-node:npmpage
stage: page
image: hosttoday/ht-docker-node:npmci
stage: metadata
script:
- npmci command npmpage --host gitlab
- npmci command npm install -g typedoc typescript
- npmci npm install
- npmci command typedoc --module "commonjs" --target "ES2016" --out public/ ts/
tags:
- docker
- notpriv
only:
- tags
artifacts:
expire_in: 1 week
paths:
- public
- public
allow_failure: true
windowsCompatibility:
image: stefanscherer/node-windows:10-build-tools
stage: metadata
script:
- npm install & npm test
coverage: /\d+.?\d+?\%\s*coverage/
tags:
- windows
allow_failure: true

View File

@ -1,13 +1,16 @@
# smartipc
# @pushrocks/smartspawn
smart subprocess handling
## Availabililty
[![npm](https://pushrocks.gitlab.io/assets/repo-button-npm.svg)](https://www.npmjs.com/package/smartipc)
[![git](https://pushrocks.gitlab.io/assets/repo-button-git.svg)](https://GitLab.com/pushrocks/smartipc)
[![git](https://pushrocks.gitlab.io/assets/repo-button-mirror.svg)](https://github.com/pushrocks/smartipc)
[![docs](https://pushrocks.gitlab.io/assets/repo-button-docs.svg)](https://pushrocks.gitlab.io/smartipc/)
## Status for master
[![build status](https://GitLab.com/pushrocks/smartipc/badges/master/build.svg)](https://GitLab.com/pushrocks/smartipc/commits/master)
[![coverage report](https://GitLab.com/pushrocks/smartipc/badges/master/coverage.svg)](https://GitLab.com/pushrocks/smartipc/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/smartipc.svg)](https://www.npmjs.com/package/smartipc)
@ -19,9 +22,11 @@ smart subprocess handling
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
## Usage
Use TypeScript for best in class instellisense.
### Understand the Purpose
smartipc makes it easy to spawn tasks into subprocesses without loosing control over what those processes do.
You can transparently call functions and expect returned data using promises.
@ -30,24 +35,23 @@ You can transparently call functions and expect returned data using promises.
**Master.ts:**
```javascript
import * as smartipc from 'smartipc'
smartipc.setBasePathArg(__dirname) // if you want to avoid typings out full paths every time
import * as smartspawn from 'smartspawn';
smartspawn.setBasePathArg(__dirname); // if you want to avoid typings out full paths every time
let myThread = new smartipc.Thread('worker')
let myThread = new smartspawn.Thread('worker');
myThread.send('someMessageOrObject').then(messageResponse => {
console.log(messageResponse)
})
console.log(messageResponse);
});
```
**worker.ts**
```javascript
```
For further information read the linked docs at the top of this README.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
> | By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy.html)
[![repo-footer](https://pushrocks.gitlab.io/assets/repo-footer.svg)](https://push.rocks)

2
assets/typescriptwrap.js Normal file
View File

@ -0,0 +1,2 @@
require('@gitzone/tsrun');
require('spawn-wrap').runMain()

5
dist/index.d.ts vendored
View File

@ -1,5 +0,0 @@
export * from './smartipc.classes.thread';
export * from './smartipc.classes.threadfunction';
export * from './smartipc.classes.threadsimple';
export * from './smartipc.classes.pool';
export * from './smartipc.wrap';

11
dist/index.js vendored
View File

@ -1,11 +0,0 @@
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./smartipc.classes.thread"));
__export(require("./smartipc.classes.threadfunction"));
__export(require("./smartipc.classes.threadsimple"));
__export(require("./smartipc.classes.pool"));
__export(require("./smartipc.wrap"));
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLCtDQUF5QztBQUN6Qyx1REFBaUQ7QUFDakQscURBQStDO0FBQy9DLDZDQUF1QztBQUN2QyxxQ0FBK0IifQ==

View File

@ -1,5 +0,0 @@
export declare class Pool {
pool: any;
constructor();
run(workerPathArg: string): any;
}

View File

@ -1,13 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartipc.plugins");
class Pool {
constructor() {
this.pool = new plugins.threads.Pool();
}
run(workerPathArg) {
return this.pool.run(workerPathArg);
}
}
exports.Pool = Pool;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpcGMuY2xhc3Nlcy5wb29sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRpcGMuY2xhc3Nlcy5wb29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOENBQTZDO0FBRTdDO0lBRUU7UUFDRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUN4QyxDQUFDO0lBQ0QsR0FBRyxDQUFDLGFBQXFCO1FBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUNyQyxDQUFDO0NBQ0Y7QUFSRCxvQkFRQyJ9

View File

@ -1,25 +0,0 @@
import { Pool } from './smartipc.classes.pool';
export declare let workerBasePath: string;
export declare let setWorkerBasePath: (basePathArg: string) => void;
export declare class Thread {
thread: any;
workerPath: string;
running: boolean;
assignedPool: Pool;
constructor(filePathArg: string);
/**
* sends a message to the spawned process
* spawns it and keeps running
*/
send<T>(message: any): Promise<T>;
/**
* sends a command once and then kills the child process
*/
sendOnce<T>(message: any): Promise<T>;
/**
* kills the thread
*/
kill(): void;
assignToPool(poolArg: Pool): void;
private checkSpawn();
}

View File

@ -1,72 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartipc.plugins");
const q = require("smartq");
exports.workerBasePath = null;
exports.setWorkerBasePath = (basePathArg) => {
exports.workerBasePath = basePathArg;
plugins.threads.config.set({
basepath: {
node: exports.workerBasePath
}
});
};
class Thread {
constructor(filePathArg) {
this.running = false;
this.assignedPool = null;
this.workerPath = filePathArg;
}
/**
* sends a message to the spawned process
* spawns it and keeps running
*/
send(message) {
let done = q.defer();
this.checkSpawn();
this.thread.send(message);
this.thread.on('message', (message) => {
done.resolve(message);
});
this.thread.on('done', (job, message) => {
done.resolve(message);
});
this.thread.on('error', err => {
done.reject(err);
});
return done.promise;
}
/**
* sends a command once and then kills the child process
*/
sendOnce(message) {
let done = q.defer();
this.send(message).then(message => {
done.resolve(message);
this.kill();
});
return done.promise;
}
/**
* kills the thread
*/
kill() {
this.thread.kill();
this.running = false;
}
assignToPool(poolArg) {
this.assignedPool = poolArg;
}
checkSpawn() {
if (!this.running && !this.assignedPool) {
this.running = true;
this.thread = plugins.threads.spawn(this.workerPath);
}
else if (!this.running && this.assignedPool) {
this.running = true;
this.thread = this.assignedPool.run(this.workerPath);
}
}
}
exports.Thread = Thread;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpcGMuY2xhc3Nlcy50aHJlYWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGlwYy5jbGFzc2VzLnRocmVhZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDhDQUE2QztBQUM3Qyw0QkFBMkI7QUFJaEIsUUFBQSxjQUFjLEdBQVcsSUFBSSxDQUFBO0FBRTdCLFFBQUEsaUJBQWlCLEdBQUcsQ0FBQyxXQUFtQjtJQUNqRCxzQkFBYyxHQUFHLFdBQVcsQ0FBQTtJQUM1QixPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7UUFDekIsUUFBUSxFQUFFO1lBQ1IsSUFBSSxFQUFFLHNCQUFjO1NBQ3JCO0tBQ0YsQ0FBQyxDQUFBO0FBQ0osQ0FBQyxDQUFBO0FBRUQ7SUFLRSxZQUFZLFdBQW1CO1FBRi9CLFlBQU8sR0FBWSxLQUFLLENBQUE7UUFDeEIsaUJBQVksR0FBUyxJQUFJLENBQUE7UUFFdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUE7SUFDL0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQUksQ0FBSSxPQUFZO1FBQ2xCLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUssQ0FBQTtRQUN2QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUE7UUFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDekIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUMsT0FBVTtZQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3ZCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxFQUFFLE9BQVU7WUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN2QixDQUFDLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHO1lBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDbEIsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUNyQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRLENBQUksT0FBTztRQUNqQixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFLLENBQUE7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBSSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTztZQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3JCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUNiLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDckIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSTtRQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7UUFDbEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUE7SUFDdEIsQ0FBQztJQUVELFlBQVksQ0FBQyxPQUFhO1FBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFBO0lBQzdCLENBQUM7SUFFTyxVQUFVO1FBQ2hCLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFBO1lBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ3RELENBQUM7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFBO1lBQ25CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQ3RELENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUE5REQsd0JBOERDIn0=

View File

@ -1,13 +0,0 @@
import 'typings-global';
export interface IThreadFunction {
(input: any, done: any): void;
}
export declare class ThreadFunction {
thread: any;
constructor(functionArg: IThreadFunction);
/**
* sends a message to the spawned process
*/
send<T>(message: any): Promise<T>;
kill(): void;
}

View File

@ -1,27 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("typings-global");
const plugins = require("./smartipc.plugins");
const q = require("smartq");
class ThreadFunction {
constructor(functionArg) {
this.thread = plugins.threads.spawn(functionArg);
}
/**
* sends a message to the spawned process
*/
send(message) {
let done = q.defer();
this.thread.send(message).on('message', (message) => {
done.resolve(message);
}).on('error', err => {
done.reject(err);
});
return done.promise;
}
kill() {
this.thread.kill();
}
}
exports.ThreadFunction = ThreadFunction;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpcGMuY2xhc3Nlcy50aHJlYWRmdW5jdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0aXBjLmNsYXNzZXMudGhyZWFkZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwQkFBdUI7QUFDdkIsOENBQTZDO0FBQzdDLDRCQUEyQjtBQU0zQjtJQUVFLFlBQVksV0FBNEI7UUFDdEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLENBQUksT0FBWTtRQUNsQixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFLLENBQUE7UUFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQVU7WUFDakQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN2QixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUc7WUFDaEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNsQixDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3JCLENBQUM7SUFFRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUNwQixDQUFDO0NBQ0Y7QUF0QkQsd0NBc0JDIn0=

View File

@ -1,9 +0,0 @@
import * as childProcess from 'child_process';
export declare class ThreadSimple {
workerPath: string;
threadChildProcess: childProcess.ChildProcess;
forkOptions: childProcess.ForkOptions;
argvArgs: string[];
constructor(filePathArg: string, argvArgs?: string[], forkOptionsArg?: childProcess.ForkOptions);
run(): Promise<childProcess.ChildProcess>;
}

View File

@ -1,29 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const plugins = require("./smartipc.plugins");
const smartq = require("smartq");
const childProcess = require("child_process");
const smartipc_classes_thread_1 = require("./smartipc.classes.thread");
class ThreadSimple {
constructor(filePathArg, argvArgs = [], forkOptionsArg = {}) {
this.workerPath = filePathArg;
this.forkOptions = forkOptionsArg;
this.argvArgs = argvArgs;
}
run() {
let done = smartq.defer();
let forkPath = (() => {
if (smartipc_classes_thread_1.workerBasePath) {
return plugins.path.join(smartipc_classes_thread_1.workerBasePath, this.workerPath);
}
else {
return this.workerPath;
}
})();
this.threadChildProcess = childProcess.fork(forkPath, this.argvArgs, this.forkOptions);
done.resolve(this.threadChildProcess);
return done.promise;
}
}
exports.ThreadSimple = ThreadSimple;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpcGMuY2xhc3Nlcy50aHJlYWRzaW1wbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGlwYy5jbGFzc2VzLnRocmVhZHNpbXBsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDhDQUE2QztBQUM3QyxpQ0FBZ0M7QUFDaEMsOENBQTZDO0FBRTdDLHVFQUEwRDtBQUUxRDtJQUtFLFlBQWEsV0FBbUIsRUFBRSxXQUFxQixFQUFFLEVBQUUsaUJBQTJDLEVBQUU7UUFDdEcsSUFBSSxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUE7UUFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxjQUFjLENBQUE7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUE7SUFDMUIsQ0FBQztJQUVELEdBQUc7UUFDRCxJQUFJLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxFQUE2QixDQUFBO1FBQ3BELElBQUksUUFBUSxHQUFHLENBQUM7WUFDZCxFQUFFLENBQUMsQ0FBQyx3Q0FBYyxDQUFDLENBQUMsQ0FBQztnQkFDbkIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHdDQUFjLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBQzNELENBQUM7WUFBQyxJQUFJLENBQUMsQ0FBQztnQkFDTixNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQTtZQUN4QixDQUFDO1FBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUNKLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUN0RixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO1FBQ3JDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3JCLENBQUM7Q0FDRjtBQXhCRCxvQ0F3QkMifQ==

View File

@ -1,5 +0,0 @@
import 'typings-global';
import * as path from 'path';
declare let threads: any;
import * as smartq from 'smartq';
export { path, smartq, threads };

View File

@ -1,10 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("typings-global");
const path = require("path");
exports.path = path;
let threads = require('threads');
exports.threads = threads;
const smartq = require("smartq");
exports.smartq = smartq;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpcGMucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0aXBjLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwQkFBdUI7QUFDdkIsNkJBQTRCO0FBS3hCLG9CQUFJO0FBSlIsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBTTVCLDBCQUFPO0FBTFgsaUNBQWdDO0FBSTVCLHdCQUFNIn0=

View File

@ -1,2 +0,0 @@
export declare let startSpawnWrap: (filePath: string, cliArgs?: string[], envArgs?: any) => void;
export declare let endSpawnWrap: () => void;

18
dist/smartipc.wrap.js vendored
View File

@ -1,18 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const spawnWrap = require("spawn-wrap");
let unwrap = null;
exports.startSpawnWrap = (filePath, cliArgs = [], envArgs = {}) => {
let spawnArray = [filePath];
for (let cliArg of cliArgs) {
spawnArray.push(cliArg);
}
unwrap = spawnWrap(spawnArray, envArgs);
};
exports.endSpawnWrap = () => {
if (unwrap) {
unwrap();
unwrap = null;
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRpcGMud3JhcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0aXBjLndyYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx3Q0FBdUM7QUFFdkMsSUFBSSxNQUFNLEdBQVEsSUFBSSxDQUFBO0FBRVgsUUFBQSxjQUFjLEdBQUcsQ0FBQyxRQUFnQixFQUFFLFVBQW9CLEVBQUUsRUFBRSxVQUFlLEVBQUU7SUFDdEYsSUFBSSxVQUFVLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUMzQixHQUFHLENBQUMsQ0FBQyxJQUFJLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzNCLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDekIsQ0FBQztJQUNELE1BQU0sR0FBRyxTQUFTLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBQ3pDLENBQUMsQ0FBQTtBQUVVLFFBQUEsWUFBWSxHQUFHO0lBQ3hCLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDWCxNQUFNLEVBQUUsQ0FBQTtRQUNSLE1BQU0sR0FBRyxJQUFJLENBQUE7SUFDZixDQUFDO0FBQ0gsQ0FBQyxDQUFBIn0=

View File

@ -1,12 +1,11 @@
{
"npmts": {
"testTs": {
"./test/*.ts": "./test/"
}
},
"npmci": {
"globalNpmTools": [
"npmts"
]
"npmts": {
"testTs": {
"./test/*.ts": "./test/"
}
},
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public"
}
}

1068
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,13 @@
{
"name": "smartipc",
"version": "1.0.9",
"name": "@pushrocks/smartspawn",
"version": "2.0.2",
"private": false,
"description": "smart subprocess handling",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "(npmts)"
"test": "tstest test/",
"build": "echo \"Not needed for now\""
},
"repository": {
"type": "git",
@ -18,16 +20,14 @@
},
"homepage": "https://gitlab.com/pushrocks/smartipc#README",
"dependencies": {
"@types/lodash": "^4.14.50",
"beautylog": "^6.0.0",
"lodash": "^4.17.4",
"smartchai": "^1.0.3",
"smartq": "^1.1.0",
"spawn-wrap": "^1.3.4",
"threads": "^0.7.2",
"typings-global": "^1.0.14"
"@pushrocks/smartpromise": "^2.0.5",
"spawn-wrap": "^1.4.2",
"threads": "^0.8.1"
},
"devDependencies": {
"typings-test": "^1.0.3"
"@gitzone/tsrun": "^1.1.9",
"@gitzone/tstest": "^1.0.12",
"@pushrocks/tapbundle": "^3.0.1",
"@types/node": "^10.5.5"
}
}

2
test/child.d.ts vendored
View File

@ -1,2 +0,0 @@
import 'typings-global';
import 'smartq';

View File

@ -1,8 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("typings-global");
require("smartq");
module.exports = (input, done) => {
done(input);
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hpbGQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjaGlsZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLDBCQUF1QjtBQUN2QixrQkFBZTtBQUNmLE1BQU0sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSTtJQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDWixDQUFDLENBQUEifQ==

View File

@ -1,5 +0,0 @@
import 'typings-global'
import 'smartq'
module.exports = (input, done) => {
done(input)
}

1
test/test.d.ts vendored
View File

@ -1 +0,0 @@
import 'typings-test';

View File

@ -1,51 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("typings-test");
const smartchai_1 = require("smartchai");
const smartipc = require("../dist/index");
let testThreadFunction;
let testThread;
let testPool;
describe('smartipc', function () {
it('should create an instance of ThreadFunction', function () {
testThreadFunction = new smartipc.ThreadFunction((input, done) => {
let url = require('url');
done(url.parse(input));
});
testThreadFunction.send('https://google.com').then(message => {
console.log(message);
testThreadFunction.kill();
});
});
it('should create an instance of Thread', function () {
smartipc.setWorkerBasePath(__dirname);
testThread = new smartipc.Thread('child.js');
testThread.send('https://google.com').then(message => {
console.log(message);
testThread.kill();
});
});
it('should not spawn when nothing is sent', function () {
smartipc.setWorkerBasePath(__dirname);
let testThread = new smartipc.Thread('child.js');
});
it('should run in a Pool', function () {
let testPool = new smartipc.Pool();
let testThread = new smartipc.Thread('child.js');
testThread.assignToPool(testPool);
return testThread.send('what').then(message => {
console.log(message);
return testThread.send('another').then(message => {
console.log(message);
testThread.assignedPool.pool.killAll();
});
});
});
it('should once', function () {
let testThread = new smartipc.Thread('child.js');
return testThread.sendOnce('what').then(message => {
smartchai_1.expect(message).to.equal('what');
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSx3QkFBcUI7QUFDckIseUNBQWtDO0FBRWxDLDBDQUF5QztBQUV6QyxJQUFJLGtCQUEyQyxDQUFBO0FBQy9DLElBQUksVUFBMkIsQ0FBQTtBQUMvQixJQUFJLFFBQXVCLENBQUE7QUFFM0IsUUFBUSxDQUFDLFVBQVUsRUFBRTtJQUNuQixFQUFFLENBQUMsNkNBQTZDLEVBQUU7UUFDaEQsa0JBQWtCLEdBQUcsSUFBSSxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsS0FBSyxFQUFFLElBQUk7WUFDM0QsSUFBSSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUE7UUFDeEIsQ0FBQyxDQUFDLENBQUE7UUFDRixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTztZQUN4RCxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3BCLGtCQUFrQixDQUFDLElBQUksRUFBRSxDQUFBO1FBQzNCLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7SUFDRixFQUFFLENBQUMscUNBQXFDLEVBQUU7UUFDeEMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ3JDLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDNUMsVUFBVSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQ2hELE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDcEIsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ25CLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsdUNBQXVDLEVBQUU7UUFDMUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQ3JDLElBQUksVUFBVSxHQUFHLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUNsRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRTtRQUN6QixJQUFJLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtRQUNsQyxJQUFJLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDaEQsVUFBVSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUNqQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTztZQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3BCLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPO2dCQUM1QyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFBO2dCQUNwQixVQUFVLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtZQUN4QyxDQUFDLENBQUMsQ0FBQTtRQUNKLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsYUFBYSxFQUFFO1FBQ2hCLElBQUksVUFBVSxHQUFHLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUNoRCxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTztZQUM3QyxrQkFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDbEMsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIn0=

View File

@ -1,54 +1,61 @@
import 'typings-test'
import { expect } from 'smartchai'
import { expect, tap } from '@pushrocks/tapbundle';
import * as smartipc from '../dist/index'
import * as smartspawn from '../ts/index';
let testThreadFunction: smartipc.ThreadFunction
let testThread: smartipc.Thread
let testPool: smartipc.Pool
let testThreadFunction: smartspawn.ThreadFunction;
let testThread: smartspawn.Thread;
let testPool: smartspawn.Pool;
describe('smartipc', function () {
it('should create an instance of ThreadFunction', function () {
testThreadFunction = new smartipc.ThreadFunction((input, done) => {
let url = require('url')
done(url.parse(input))
})
testThreadFunction.send('https://google.com').then(message => {
console.log(message)
testThreadFunction.kill()
})
})
it('should create an instance of Thread', function () {
smartipc.setWorkerBasePath(__dirname)
testThread = new smartipc.Thread('child.js')
testThread.send('https://google.com').then(message => {
console.log(message)
testThread.kill()
})
})
/**
* create a normal ThreadFunction
*/
tap.test('should create an instance of ThreadFunction', async () => {
testThreadFunction = new smartspawn.ThreadFunction((input, done) => {
let url = require('url');
done(url.parse(input));
});
const message = await testThreadFunction.send('https://google.com');
console.log(message);
testThreadFunction.kill();
});
it('should not spawn when nothing is sent', function () {
smartipc.setWorkerBasePath(__dirname)
let testThread = new smartipc.Thread('child.js')
})
tap.test('should create an instance of Thread', async () => {
smartspawn.setWorkerBasePath(__dirname);
testThread = new smartspawn.Thread('../testassets/child.ts');
testThread.enableTypeScript();
const message = await testThread.send('https://google.com');
console.log(message);
testThread.kill();
});
it('should run in a Pool', function () {
let testPool = new smartipc.Pool()
let testThread = new smartipc.Thread('child.js')
testThread.assignToPool(testPool)
return testThread.send('what').then(message => {
console.log(message)
return testThread.send('another').then(message => {
console.log(message)
testThread.assignedPool.pool.killAll()
})
})
})
tap.test('should not spawn when nothing is sent', async () => {
smartspawn.setWorkerBasePath(__dirname);
let testThread = new smartspawn.Thread('../testassets/child.ts');
});
it('should once', function () {
let testThread = new smartipc.Thread('child.js')
return testThread.sendOnce('what').then(message => {
expect(message).to.equal('what')
})
})
})
tap.test('should run in a Pool', async () => {
let testPool = new smartspawn.Pool();
let testThread = new smartspawn.Thread('../testassets/child.ts');
testThread.assignToPool(testPool);
// first run
let message = await testThread.send('what');
expect(message).to.equal('what');
console.log(message);
// second run
message = await testThread.send('another');
expect(message).to.equal('another');
console.log(message);
// kill all
testThread.assignedPool.pool.killAll();
});
tap.test('should once', async () => {
let testThread = new smartspawn.Thread('../testassets/child.ts');
const message = await testThread.sendOnce('what');
expect(message).to.equal('what');
});
tap.start();

3
testassets/child.ts Normal file
View File

@ -0,0 +1,3 @@
module.exports = (input, done) => {
done(input);
};

View File

@ -1,6 +1,5 @@
export * from './smartipc.classes.thread'
export * from './smartipc.classes.threadfunction'
export * from './smartipc.classes.threadsimple'
export * from './smartipc.classes.pool'
export * from './smartipc.wrap'
export * from './smartspawn.classes.thread';
export * from './smartspawn.classes.threadfunction';
export * from './smartspawn.classes.threadsimple';
export * from './smartspawn.classes.pool';
export * from './smartspawn.wrap';

View File

@ -1,11 +0,0 @@
import * as plugins from './smartipc.plugins'
export class Pool {
pool
constructor() {
this.pool = new plugins.threads.Pool()
}
run(workerPathArg: string) {
return this.pool.run(workerPathArg)
}
}

View File

@ -1,79 +0,0 @@
import * as plugins from './smartipc.plugins'
import * as q from 'smartq'
import { Pool } from './smartipc.classes.pool'
export let workerBasePath: string = null
export let setWorkerBasePath = (basePathArg: string) => {
workerBasePath = basePathArg
plugins.threads.config.set({
basepath: {
node: workerBasePath
}
})
}
export class Thread {
thread
workerPath: string
running: boolean = false
assignedPool: Pool = null
constructor(filePathArg: string) {
this.workerPath = filePathArg
}
/**
* sends a message to the spawned process
* spawns it and keeps running
*/
send<T>(message: any): Promise<T> {
let done = q.defer<T>()
this.checkSpawn()
this.thread.send(message)
this.thread.on('message', (message: T) => {
done.resolve(message)
})
this.thread.on('done', (job, message: T) => {
done.resolve(message)
})
this.thread.on('error', err => {
done.reject(err)
})
return done.promise
}
/**
* sends a command once and then kills the child process
*/
sendOnce<T>(message): Promise<T> {
let done = q.defer<T>()
this.send<T>(message).then(message => {
done.resolve(message)
this.kill()
})
return done.promise
}
/**
* kills the thread
*/
kill() {
this.thread.kill()
this.running = false
}
assignToPool(poolArg: Pool) {
this.assignedPool = poolArg
}
private checkSpawn() {
if (!this.running && !this.assignedPool) {
this.running = true
this.thread = plugins.threads.spawn(this.workerPath)
} else if (!this.running && this.assignedPool) {
this.running = true
this.thread = this.assignedPool.run(this.workerPath)
}
}
}

View File

@ -1,31 +0,0 @@
import 'typings-global'
import * as plugins from './smartipc.plugins'
import * as q from 'smartq'
export interface IThreadFunction {
(input, done): void
}
export class ThreadFunction {
thread
constructor(functionArg: IThreadFunction) {
this.thread = plugins.threads.spawn(functionArg)
}
/**
* sends a message to the spawned process
*/
send<T>(message: any): Promise<T> {
let done = q.defer<T>()
this.thread.send(message).on('message', (message: T) => {
done.resolve(message)
}).on('error', err => {
done.reject(err)
})
return done.promise
}
kill() {
this.thread.kill()
}
}

View File

@ -1,31 +0,0 @@
import * as plugins from './smartipc.plugins'
import * as smartq from 'smartq'
import * as childProcess from 'child_process'
import { workerBasePath } from './smartipc.classes.thread'
export class ThreadSimple {
workerPath: string
threadChildProcess: childProcess.ChildProcess
forkOptions: childProcess.ForkOptions
argvArgs: string[]
constructor (filePathArg: string, argvArgs: string[] = [], forkOptionsArg: childProcess.ForkOptions = {}) {
this.workerPath = filePathArg
this.forkOptions = forkOptionsArg
this.argvArgs = argvArgs
}
run () {
let done = smartq.defer<childProcess.ChildProcess>()
let forkPath = (() => {
if (workerBasePath) {
return plugins.path.join(workerBasePath, this.workerPath)
} else {
return this.workerPath
}
})()
this.threadChildProcess = childProcess.fork(forkPath, this.argvArgs, this.forkOptions)
done.resolve(this.threadChildProcess)
return done.promise
}
}

View File

@ -1,10 +0,0 @@
import 'typings-global'
import * as path from 'path'
let threads = require('threads')
import * as smartq from 'smartq'
export {
path,
smartq,
threads
}

View File

@ -1,18 +0,0 @@
import * as spawnWrap from 'spawn-wrap'
let unwrap: any = null
export let startSpawnWrap = (filePath: string, cliArgs: string[] = [], envArgs: any = {}) => {
let spawnArray = [filePath]
for (let cliArg of cliArgs) {
spawnArray.push(cliArg)
}
unwrap = spawnWrap(spawnArray, envArgs)
}
export let endSpawnWrap = () => {
if (unwrap) {
unwrap()
unwrap = null
}
}

View File

@ -0,0 +1,6 @@
// ==============
// This file handles clustering of nodejs programs
// ==============
import * as plugins from './smartspawn.plugins';
export class Cluster {}

View File

@ -0,0 +1,13 @@
import * as plugins from './smartspawn.plugins';
export class Pool {
pool;
// the constructor for pool
constructor() {
this.pool = new plugins.threads.Pool();
}
run(workerPathArg: string) {
return this.pool.run(workerPathArg);
}
}

View File

@ -0,0 +1,85 @@
import * as plugins from './smartspawn.plugins';
import * as paths from './smartspawn.paths';
import * as q from 'smartq';
import { Pool } from './smartspawn.classes.pool';
import { startSpawnWrap, endSpawnWrap } from './smartspawn.wrap';
export let workerBasePath: string = null;
export const setWorkerBasePath = (basePathArg: string) => {
workerBasePath = basePathArg;
plugins.threads.config.set({
basepath: {
node: workerBasePath
}
});
};
export class Thread {
thread;
workerPath: string;
running: boolean = false;
assignedPool: Pool = null;
constructor(filePathArg: string) {
this.workerPath = filePathArg;
}
/**
* sends a message to the spawned process
* spawns it and keeps running
*/
send<T>(message: any): Promise<T> {
let done = q.defer<T>();
this._checkSpawn();
this.thread.send(message);
this.thread.on('message', (message: T) => {
done.resolve(message);
});
this.thread.on('done', (job, message: T) => {
done.resolve(message);
});
this.thread.on('error', err => {
done.reject(err);
});
return done.promise;
}
/**
* sends a command once and then kills the child process
*/
sendOnce<T>(message): Promise<T> {
let done = q.defer<T>();
this.send<T>(message).then(message => {
done.resolve(message);
this.kill();
});
return done.promise;
}
/**
* kills the thread
*/
kill() {
this.thread.kill();
this.running = false;
}
assignToPool(poolArg: Pool) {
this.assignedPool = poolArg;
}
enableTypeScript () {
// TODO:
}
private _checkSpawn() {
if (!this.running && !this.assignedPool) {
this.running = true;
this.thread = plugins.threads.spawn(this.workerPath);
} else if (!this.running && this.assignedPool) {
this.running = true;
this.thread = this.assignedPool.run(this.workerPath);
}
}
}

View File

@ -0,0 +1,34 @@
import 'typings-global';
import * as plugins from './smartspawn.plugins';
import * as q from 'smartq';
export interface IThreadFunction {
(input, done): void;
}
export class ThreadFunction {
thread;
constructor(functionArg: IThreadFunction) {
this.thread = plugins.threads.spawn(functionArg);
}
/**
* sends a message to the spawned process
*/
send<T>(message: any): Promise<T> {
let done = q.defer<T>();
this.thread
.send(message)
.on('message', (message: T) => {
done.resolve(message);
})
.on('error', err => {
done.reject(err);
});
return done.promise;
}
kill() {
this.thread.kill();
}
}

View File

@ -0,0 +1,35 @@
import * as plugins from './smartspawn.plugins';
import * as smartq from 'smartq';
import * as childProcess from 'child_process';
import { workerBasePath } from './smartspawn.classes.thread';
export class ThreadSimple {
workerPath: string;
threadChildProcess: childProcess.ChildProcess;
forkOptions: childProcess.ForkOptions;
argvArgs: string[];
constructor(
filePathArg: string,
argvArgs: string[] = [],
forkOptionsArg: childProcess.ForkOptions = {}
) {
this.workerPath = filePathArg;
this.forkOptions = forkOptionsArg;
this.argvArgs = argvArgs;
}
run() {
let done = smartq.defer<childProcess.ChildProcess>();
let forkPath = (() => {
if (workerBasePath) {
return plugins.path.join(workerBasePath, this.workerPath);
} else {
return this.workerPath;
}
})();
this.threadChildProcess = childProcess.fork(forkPath, this.argvArgs, this.forkOptions);
done.resolve(this.threadChildProcess);
return done.promise;
}
}

4
ts/smartspawn.paths.ts Normal file
View File

@ -0,0 +1,4 @@
import * as plugins from './smartspawn.plugins'
export const packageBase = plugins.path.join(__dirname, '../');
export const typescriptwrapJs = plugins.path.join(packageBase, 'assets/typescriptwrap.js');

5
ts/smartspawn.plugins.ts Normal file
View File

@ -0,0 +1,5 @@
import * as path from 'path';
let threads = require('threads');
import * as smartpromise from '@pushrocks/smartpromise';
export { path, smartpromise, threads };

18
ts/smartspawn.wrap.ts Normal file
View File

@ -0,0 +1,18 @@
import * as spawnWrap from 'spawn-wrap';
let unwrap: any = null;
export const startSpawnWrap = (filePath: string, cliArgs: string[] = [], envArgs: any = {}) => {
let spawnArray = [filePath];
for (let cliArg of cliArgs) {
spawnArray.push(cliArg);
}
unwrap = spawnWrap(spawnArray, envArgs);
};
export const endSpawnWrap = () => {
if (unwrap) {
unwrap();
unwrap = null;
}
};

423
yarn.lock
View File

@ -1,423 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/chai-as-promised@0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-0.0.29.tgz#43d52892aa998e185a3de3e2477edb8573be1d77"
dependencies:
"@types/chai" "*"
"@types/promises-a-plus" "*"
"@types/chai-string@^1.1.30":
version "1.1.30"
resolved "https://registry.yarnpkg.com/@types/chai-string/-/chai-string-1.1.30.tgz#4d8744b31a5a2295fc01c981ed1e2d4c8a070f0a"
dependencies:
"@types/chai" "*"
"@types/chai@*", "@types/chai@^3.4.35":
version "3.4.35"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-3.4.35.tgz#e8d65f83492d2944f816fc620741821c28a8c900"
"@types/lodash@4.x.x", "@types/lodash@^4.14.50":
version "4.14.54"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.54.tgz#287dbbcd97d5da69c25ca99fb5afa81c4839b7fa"
"@types/mocha@^2.2.31":
version "2.2.39"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.39.tgz#f68d63db8b69c38e9558b4073525cf96c4f7a829"
"@types/promises-a-plus@*":
version "0.0.27"
resolved "https://registry.yarnpkg.com/@types/promises-a-plus/-/promises-a-plus-0.0.27.tgz#c64651134614c84b8f5d7114ce8901d36a609780"
"@types/q@0.x.x":
version "0.0.32"
resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5"
ansi-256-colors@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz#910de50efcc7c09e3d82f2f87abd6b700c18818a"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
assertion-error@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c"
balanced-match@^0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
beautycolor@^1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/beautycolor/-/beautycolor-1.0.7.tgz#a4715738ac4c8221371e9cbeb5a6cc6d11ecbf7c"
dependencies:
ansi-256-colors "^1.1.0"
typings-global "^1.0.14"
beautylog@^6.0.0:
version "6.1.1"
resolved "https://registry.yarnpkg.com/beautylog/-/beautylog-6.1.1.tgz#2a83603ad7e2a0a09701ac63d7d3064a588dc779"
dependencies:
"@types/lodash" "4.x.x"
beautycolor "^1.0.5"
figlet "^1.2.0"
lodash "^4.17.4"
ora "^1.1.0"
smartenv "^2.0.0"
smartq "^1.0.4"
typings-global "^1.0.14"
brace-expansion@^1.0.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9"
dependencies:
balanced-match "^0.4.1"
concat-map "0.0.1"
chai-as-promised@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-6.0.0.tgz#1a02a433a6f24dafac63b9c96fa1684db1aa8da6"
dependencies:
check-error "^1.0.2"
chai-string@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/chai-string/-/chai-string-1.3.0.tgz#df6139f294391b1035be5606f60a843b3a5041e7"
chai@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247"
dependencies:
assertion-error "^1.0.1"
deep-eql "^0.1.3"
type-detect "^1.0.0"
chalk@^1.0.0, chalk@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
dependencies:
restore-cursor "^2.0.0"
cli-spinners@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.0.0.tgz#ef987ed3d48391ac3dab9180b406a742180d6e6a"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
cross-spawn@^4:
version "4.0.2"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41"
dependencies:
lru-cache "^4.0.1"
which "^1.2.9"
deep-eql@^0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2"
dependencies:
type-detect "0.1.1"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
eventemitter3@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.2.tgz#20ce4891909ce9f35b088c94fab40e2c96f473ac"
figlet@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.2.0.tgz#6c46537378fab649146b5a6143dda019b430b410"
foreground-child@^1.5.6:
version "1.5.6"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9"
dependencies:
cross-spawn "^4"
signal-exit "^3.0.0"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
glob@^7.0.0, glob@^7.0.5:
version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.2"
once "^1.3.0"
path-is-absolute "^1.0.0"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
interpret@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c"
isexe@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0"
lodash@^4.17.2, lodash@^4.17.4:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"
dependencies:
chalk "^1.0.0"
lru-cache@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e"
dependencies:
pseudomap "^1.0.1"
yallist "^2.0.0"
mimic-fn@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
minimatch@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
dependencies:
brace-expansion "^1.0.0"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
native-promise-only@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
onetime@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.0.tgz#52aa8110e52fc5126ffc667bd8ec21c2ed209ce6"
dependencies:
mimic-fn "^1.0.0"
ora@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-1.1.0.tgz#69aaa4a209630e43b142c5f7ff41820da87e2faf"
dependencies:
chalk "^1.1.1"
cli-cursor "^2.1.0"
cli-spinners "^1.0.0"
log-symbols "^1.0.2"
os-homedir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
pseudomap@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
q@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
dependencies:
resolve "^1.1.6"
resolve@^1.1.6:
version "1.3.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235"
dependencies:
path-parse "^1.0.5"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
dependencies:
onetime "^2.0.0"
signal-exit "^3.0.2"
rimraf@^2.3.3:
version "2.6.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
dependencies:
glob "^7.0.5"
semver@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
shelljs@^0.7.4:
version "0.7.6"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad"
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
signal-exit@^2.0.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-2.1.2.tgz#375879b1f92ebc3b334480d038dc546a6d558564"
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
smartchai@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/smartchai/-/smartchai-1.0.3.tgz#de6d010bb8b5aef24cb70b31a5f5334e8c41b72f"
dependencies:
"@types/chai" "^3.4.35"
"@types/chai-as-promised" "0.0.29"
"@types/chai-string" "^1.1.30"
chai "^3.5.0"
chai-as-promised "^6.0.0"
chai-string "^1.3.0"
smartenv@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/smartenv/-/smartenv-2.0.0.tgz#ede4e2044efcf9bec318388bb1dab53024ee3d16"
dependencies:
"@types/q" "0.x.x"
lodash "^4.17.2"
q "^1.4.1"
typings-global "^1.0.14"
smartq@^1.0.4, smartq@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/smartq/-/smartq-1.1.1.tgz#efb358705260d41ae18aef7ffd815f7b6fe17dd3"
dependencies:
typed-promisify "^0.3.0"
typings-global "^1.0.14"
spawn-wrap@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.4.tgz#5d133070fef81cd26d8259acaa07fc1a86fd45dc"
dependencies:
foreground-child "^1.5.6"
mkdirp "^0.5.0"
os-homedir "^1.0.1"
rimraf "^2.3.3"
signal-exit "^2.0.0"
which "^1.2.4"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
threads@^0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/threads/-/threads-0.7.2.tgz#852ab7053d43a1dd3b3ef88e1563abb6245068bf"
dependencies:
eventemitter3 "^2.0.2"
native-promise-only "^0.8.1"
type-detect@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822"
type-detect@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2"
typed-promisify@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/typed-promisify/-/typed-promisify-0.3.0.tgz#1ba0af5e444c87d8047406f18ce49092a1191853"
typings-global@*, typings-global@^1.0.14:
version "1.0.14"
resolved "https://registry.yarnpkg.com/typings-global/-/typings-global-1.0.14.tgz#ab682720a03d6b9278869fb5c30c30d7dc61d12c"
dependencies:
semver "^5.3.0"
shelljs "^0.7.4"
typings-test@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/typings-test/-/typings-test-1.0.3.tgz#fbab895eb3f0c44842e73db059f65946b971e369"
dependencies:
"@types/mocha" "^2.2.31"
typings-global "*"
which@^1.2.4, which@^1.2.9:
version "1.2.12"
resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192"
dependencies:
isexe "^1.1.1"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
yallist@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4"