-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support single process mode (#3430)
- Loading branch information
1 parent
1336169
commit 20ba463
Showing
14 changed files
with
525 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
'use strict'; | ||
|
||
const LocalMessenger = require('./local'); | ||
const IPCMessenger = require('./ipc'); | ||
|
||
exports.create = egg => { | ||
return egg.options.mode === 'single' | ||
? new LocalMessenger(egg) | ||
: new IPCMessenger(egg); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
'use strict'; | ||
|
||
const debug = require('debug')('egg:util:messenger:local'); | ||
const is = require('is-type-of'); | ||
const EventEmitter = require('events'); | ||
|
||
/** | ||
* Communication between app worker and agent worker with EventEmitter | ||
*/ | ||
class Messenger extends EventEmitter { | ||
|
||
constructor(egg) { | ||
super(); | ||
this.egg = egg; | ||
} | ||
|
||
/** | ||
* Send message to all agent and app | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
* @return {Messenger} this | ||
*/ | ||
broadcast(action, data) { | ||
debug('[%s] broadcast %s with %j', this.pid, action, data); | ||
this.send(action, data, 'both'); | ||
return this; | ||
} | ||
|
||
/** | ||
* send message to the specified process | ||
* Notice: in single process mode, it only can send to self process, | ||
* and it will send to both agent and app's messengers. | ||
* @param {String} pid - the process id of the receiver | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
* @return {Messenger} this | ||
*/ | ||
sendTo(pid, action, data) { | ||
debug('[%s] send %s with %j to %s', this.pid, action, data, pid); | ||
if (pid !== process.pid) return; | ||
this.send(action, data, 'both'); | ||
return this; | ||
} | ||
|
||
/** | ||
* send message to one worker by random | ||
* Notice: in single process mode, we only start one agent worker and one app worker | ||
* - if it's running in agent, it will send to one of app workers | ||
* - if it's running in app, it will send to agent | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
* @return {Messenger} this | ||
*/ | ||
sendRandom(action, data) { | ||
debug('[%s] send %s with %j to opposite', this.pid, action, data); | ||
this.send(action, data, 'opposite'); | ||
return this; | ||
} | ||
|
||
/** | ||
* send message to app | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
* @return {Messenger} this | ||
*/ | ||
sendToApp(action, data) { | ||
debug('[%s] send %s with %j to all app', this.pid, action, data); | ||
this.send(action, data, 'application'); | ||
return this; | ||
} | ||
|
||
/** | ||
* send message to agent | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
* @return {Messenger} this | ||
*/ | ||
sendToAgent(action, data) { | ||
debug('[%s] send %s with %j to all agent', this.pid, action, data); | ||
this.send(action, data, 'agent'); | ||
return this; | ||
} | ||
|
||
/** | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
* @param {String} to - let master know how to send message | ||
* @return {Messenger} this | ||
*/ | ||
send(action, data, to) { | ||
const { egg } = this; | ||
let application; | ||
let agent; | ||
let opposite; | ||
if (egg.type === 'application') { | ||
application = egg; | ||
agent = egg.agent; | ||
opposite = agent; | ||
} else { | ||
agent = egg; | ||
application = egg.application; | ||
opposite = application; | ||
} | ||
|
||
// use nextTick to keep it async as IPC messenger | ||
process.nextTick(() => { | ||
if (application.messenger && (to === 'application' || to === 'both')) { | ||
application.messenger._onMessage({ action, data }); | ||
} | ||
if (agent.messenger && (to === 'agent' || to === 'both')) { | ||
agent.messenger._onMessage({ action, data }); | ||
} | ||
if (opposite.messenger && to === 'opposite') { | ||
opposite.messenger._onMessage({ action, data }); | ||
} | ||
}); | ||
|
||
return this; | ||
} | ||
|
||
_onMessage(message) { | ||
if (message && is.string(message.action)) { | ||
debug('[%s] got message %s with %j', this.pid, message.action, message.data); | ||
this.emit(message.action, message.data); | ||
} | ||
} | ||
|
||
close() { | ||
this.removeAllListeners(); | ||
} | ||
|
||
/** | ||
* @method Messenger#on | ||
* @param {String} action - message key | ||
* @param {Object} data - message value | ||
*/ | ||
} | ||
|
||
module.exports = Messenger; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
'use strict'; | ||
|
||
const detectPort = require('detect-port'); | ||
const Application = require('./application'); | ||
const Agent = require('./agent'); | ||
|
||
module.exports = async (options = {}) => { | ||
console.warn('single process mode is still in experiment, please don\'t use it in production environment'); | ||
|
||
options.baseDir = options.baseDir || process.cwd(); | ||
options.mode = 'single'; | ||
// FIXME: cluster-client support single process mode | ||
options.clusterPort = await detectPort(); | ||
const agent = new Agent(Object.assign({}, options)); | ||
await agent.ready(); | ||
const application = new Application(Object.assign({}, options)); | ||
application.agent = agent; | ||
agent.application = application; | ||
await application.ready(); | ||
|
||
// emit egg-ready message in agent and application | ||
application.messenger.broadcast('egg-ready'); | ||
|
||
return application; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const egg = require('../../../../'); | ||
|
||
egg.start().then(app => { | ||
app.listen(3000); | ||
console.log('listen 3000'); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.