node-process-bearer v0.0.22
node-process-bearer
Simple nodejs process toolkit
Introduce
This project is used to running Node code as child process, In spite of Node(EcmaScript) code is designed to running on single process, But it's easy to design a project which running on mutil-process with Node child_process.
StartUp
npm install node-process-bearer
Path Structure
--Root
|
|--Module1
| |--service.js
| |--worker1.js
| |--config.js
|
|--Module2
| |--service.js
| |--worker1.js
| |--worker2.js
| |--config.js
|
|--conf.json
1. Create conf.json
create root/conf.json like:
{
"manage_port": 8200,//manage port
"log_conf": { //logger config
"logLevel": 0, // see detail @LOG_LEVEL
"showLineNumber": false, // value `true` or `false`), show line number or not
"path": "/var/log/bearer" // save path of log, TODO
},
"modules": [{
name:"Module1",//module(path) name
start_mode:"fork",//TODO [fork, spawn, exec]
argv:[""] //TODO
},
{
name:"Module2",//module(path) name
start_mode:"exec",//TODO [fork, spawn, exec]
argv:[""] //TODO
}]
}
2. Create your module
2.1 Create module path
mkdir Module1
cd your module path
cd Module1
create service.js
and define export_func
//export_func
const export_func = {
name: "Module1" //same as Module name
getNewWorld: function() {
return ["testModule2", "New", "World"];
},
// async
asyncGetNewWorld: function(ext) {
return new Promise((resolve, reject) => {
logger.info("[testModule1] ext: " + JSON.stringify(ext));
asyncCall(ext, ret => {
resolve(ret);
});
});
}
};
2.1.1 define sync/async/promise function
sync function:
getNewWorld: function(ext) {
return ["testModule1", "New", "World"];
}
async function:
asyncGetNewWorld: (ext, callback) => {
let retVal = [JSON.stringify(ext), "From Module1"];
setTimeout(() => {
callback(retVal);
}, 2000);
}
promise function:
resolveGetNewWorld: (ext) => {
return new Promise((resolve, reject) => {
let retVal = [JSON.stringify(ext), "From Module1"];
setTimeout(() => {
resolve(retVal);
}, 2000);
});
}
2.2 Import Courier
const Courier = require("node-process-bearer").Courier;
2.3 Init new courier object
let courier = new Courier(export_func);
Your should defined all exported function in export_func
, which can be called from other module.
2.4 Call function Courier.listening to sustaining your module as well as creating your interval job here
courier.listening();
or
courier.listening(() => {
logger.info("defined interval job");
});
3. Send IPC calling
3.1 sync
courier.sendCall(module name, method, callback, param1, param2...);
like:
courier.sendCall("Module1", "getNewWorld", ret => {
logger.info("[testModule2] callModule1:" + JSON.stringify(ret));
}, "oh", "yeah");
3.2 async
method must be sened with "sendAsyncCall"
courier.sendAsyncCall("Module1", "asyncGetNewWorld", ret => {
logger.info("[testModule3] callModule1 ret:" + JSON.stringify(ret));
}, "oh", "yeah");
3.2.1 promise/callback
courier.sendAsyncCall("Module1", "resolveGetNewWorld", ret => {
logger.info("[Module2] call callModule1 promise resolveGetNewWorld ret:" + JSON.stringify(ret));
}, "call promise func", " as callback");
3.2.2 promise flow
courier.sendAsyncCall("Module1", "resolveGetNewWorld", "", "callWithPromiseFlow")
.then(ret => {
logger.info("[Module2] call callModule1 promise resolveGetNewWorld ret:" + JSON.stringify(ret));
})
.catch(err => {
logger.info("[Module2] call callModule1 err:" + JSON.stringify(err));
});
3.2.3 async/await
try {
let ret = await courier.sendAsyncCall("Module1", "resolveGetNewWorld", "", "callWithAwaitFlow");
logger.info("[Module2] callModule1 await resolveGetNewWorld ret:" + JSON.stringify(ret))
} catch (err) {
logger.info("[Module2] callModule1 await resolveGetNewWorld err:" + JSON.stringify(err));
}
async function usually start with "async"
4. Manage your Process-List
Sending inner request as commander to managing your module.
http://127.0.0.1:8200/npb/list
: display process list
http://127.0.0.1:8200/npb/restart?target={module_name}
: restart process with module name
5. Start bearer
$ bearer modules.json conf.json
[2017-8-28 17:52:59] Main Process Start
[2017-8-28 17:52:59] Manager Port: 8200
[2017-8-28 17:52:59] child module start pid:14286, name: Module1
[2017-8-28 17:52:59] child module start pid:14287, name: Module2
use npm link
or npm install node-process-bearer -g
to binding bash command bearer
, or start project with node node_modules/node-process-bearer/bin/bearer.js
See More detail @example
Extra
logger
Import logger if you need
const logger = require("node-process-bearer").logger.getLogger();
use log function like:
logger.info("[hello] World");
set log config like:
const logger = require("node-process-bearer").logger.getLogger({
logLevel: logger.LOG_LEVEL.INFO,
showLineNumber: false
});
or
const logger = require("node-process-bearer").logger.getLogger();
logger.setConf({
logLevel: logger.LOG_LEVEL.INFO,
showLineNumber: false
});
Data Structure
job
{
unique_id: "module name + ts", //unique id of the job
from: "demo1",
to: "demo2",
content: {
type: "call", //["call", "receipt"]
func: "",
params: {
param1: value1,
param2: value2
}
},
status: "sended", // ["new", "sended", "received", "resolved", "rejected"]
}
============ 中文分割线 =============
node-process-bearer
一个简单的,使用process管理模块的小工具
介绍
众所周知,JavaScript(EcmaScript)是没有进程/线程概念的,而作为EcmaScript的一个实现,Nodejs是可以进行多进程的管理与操作,本工程就通过使用Nodejs的child_process实现了一个多进程的模块调用工具
开始
npm install node-process-bearer
目录结构
--Root
|
|--Module1
| |--service.js
| |--worker1.js
| |--config.js
|
|--Module2
| |--service.js
| |--worker1.js
| |--worker2.js
| |--config.js
|
|--conf.json
1.创建 modules.json 与 conf.json
root/conf.json 长这样:
{
"manage_port": 8200,
"log_conf": {
"logLevel": 0,
"showLineNumber": false,
"path": "/var/log/bearer"
},
"modules": [{
name:"Module1",
start_mode:"fork",
argv:[""]
},
{
name:"Module2",
start_mode:"exec",
argv:[""]
}]
}
参数说明: manage_port: 模块管理的后端接口 log_conf: logger配置项 modules: 启动模块配置,启动的模块信息定义于此
2. 创建模块
2.1 创建模块目录
mkdir Module1
进入你的模块目录
cd Module1
创建 service.js
并定义 export_func
//export_func
const export_func = {
name: "Module1" //same as Module name
// 同步方法
getNewWorld: function() {
return ["testModule2", "New", "World"];
}
// 异步方法
asyncGetNewWorld: function(ext) {
return new Promise((resolve, reject) => {
logger.info("[testModule1] ext: " + JSON.stringify(ext));
asyncCall(ext, ret => {
resolve(ret);
});
});
}
};
2.1.1 定义 sync/async/promise 方法
同步方法:
getNewWorld: function(ext) {
return ["testModule1", "New", "World"];
}
异步方法:
asyncGetNewWorld: (ext, callback) => {
let retVal = [JSON.stringify(ext), "From Module1"];
setTimeout(() => {
callback(retVal);
}, 2000);
}
promise:
resolveGetNewWorld: (ext) => {
return new Promise((resolve, reject) => {
let retVal = [JSON.stringify(ext), "From Module1"];
setTimeout(() => {
resolve(retVal);
}, 2000);
});
}
2.2 引入 Courier
const Courier = require("node-process-bearer").Courier;
2.3 实例化Courier
let courier = new Courier(export_func);
你必须将你所有的模块间调用的方法定义在 export_func
中
2.4 调用courier.listening()以保持你的模块持续运行在子进程中(node进程执行完会自动退出),当然,你也可以在listening中定义自己的定时任务
courier.listening();
或者
courier.listening(() => {
logger.info("defined interval job");
});
3. 进程间调用
进程间调用的方法如下:
3.1 同步调用
courier.sendCall("模块名称", "调用的方法", "回调方法", 参数1, 参数2...);
例如:
courier.sendCall("Module1", "getNewWorld", ret => {
logger.info("[testModule2] callModule1:" + JSON.stringify(ret));
}, "oh", "yeah");
3.2 异步调用
调用异步方法必须使用 sendAsyncCall
courier.sendAsyncCall("Module1", "asyncGetNewWorld", ret => {
logger.info("[testModule3] callModule1 ret:" + JSON.stringify(ret));
}, "oh", "yeah");
3.2.1 用回调的方式调用异步方法(可以是promise)
courier.sendAsyncCall("Module1", "resolveGetNewWorld", ret => {
logger.info("[Module2] call callModule1 promise resolveGetNewWorld ret:" + JSON.stringify(ret));
}, "call promise func", " as callback");
3.2.2 promise流
courier.sendAsyncCall("Module1", "resolveGetNewWorld", "", "callWithPromiseFlow")
.then(ret => {
logger.info("[Module2] call callModule1 promise resolveGetNewWorld ret:" + JSON.stringify(ret));
})
.catch(err => {
logger.info("[Module2] call callModule1 err:" + JSON.stringify(err));
});
3.2.3 async/await
try {
let ret = await courier.sendAsyncCall("Module1", "resolveGetNewWorld", "", "callWithAwaitFlow");
logger.info("[Module2] callModule1 await resolveGetNewWorld ret:" + JSON.stringify(ret))
} catch (err) {
logger.info("[Module2] callModule1 await resolveGetNewWorld err:" + JSON.stringify(err));
}
4. 管理你的子进程
可通过本地http服务来管理子进程,你可以在conf.json
中修改你的管理端口
http://127.0.0.1:8200/npb/list
: 显示当前进程列表
http://127.0.0.1:8200/npb/restart?target={module_name}
: 重启进程
5. 启动命令
$ bearer modules.json conf.json
[2017-8-28 17:52:59] Main Process Start
[2017-8-28 17:52:59] Manager Port: 8200
[2017-8-28 17:52:59] child module start pid:14286, name: Module1
[2017-8-28 17:52:59] child module start pid:14287, name: Module2
如果提示没有bearer这个命令,可以通过npm install node-process-beare -g
或者npm link
命令来注册bearer命令,也可以直接使用node node_modules/node-process-bearer/bin/bearer.js
命令启动
更多示例可参考 example 目录下的例子
额外的部分
logger
通过简单包装console.log实现了一个logger,如果你想使用,可以通过如下方式:
const logger = require("node-process-bearer").logger.getLogger();
打印log时:
logger.info("[hello] World");
可按如下方式配置:
const logger = require("node-process-bearer").logger.getLogger({
logLevel: logger.LOG_LEVEL.INFO,
showLineNumber: false
});
or
const logger = require("node-process-bearer").logger.getLogger();
logger.setConf({
logLevel: logger.LOG_LEVEL.INFO,
showLineNumber: false
});
一些数据结构
job
{
unique_id: "module name + ts", //unique id of the job
from: "demo1",
to: "demo2",
content: {
type: "call", //["call", "receipt"]
func: "",
params: {
param1: value1,
param2: value2
}
},
status: "sended", // ["new", "sended", "received", "resolved", "rejected"]
}
只有中文的后记
这是个无聊的工程....初衷仅仅是在使用pm2时, 能够仅仅重启某部分的模块(让restart数字好看点....),整个工程陆陆续续改了一个月,当然, 或许这里将会永远无人过问,那就让它继续默默无闻吧,跟他的作者一样.....
以此纪念个人第一个发布的工程
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago