pomelo-upgrade
Version:
150 lines (127 loc) • 4.31 kB
JavaScript
'use strict';
const fs = require('fs');
const path = require('path');
const protobuf = require('pomelo-protobuf');
const Constants = require('../util/constants');
const crypto = require('crypto');
const logger = require('pomelo-logger-upgrade').getLogger('pomelo', __filename);
class ProtobuffComponent
{
constructor(app, opts)
{
this.app = app;
opts = opts || {};
this.watchers = {};
this.serverProtos = {};
this.clientProtos = {};
this.version = '';
const env = app.get(Constants.RESERVED.ENV);
const originServerPath = path.join(app.getBase(), Constants.FILEPATH.SERVER_PROTOS);
const presentServerPath = path.join(Constants.FILEPATH.CONFIG_DIR, env, path.basename(Constants.FILEPATH.SERVER_PROTOS));
const originClientPath = path.join(app.getBase(), Constants.FILEPATH.CLIENT_PROTOS);
const presentClientPath = path.join(Constants.FILEPATH.CONFIG_DIR, env, path.basename(Constants.FILEPATH.CLIENT_PROTOS));
this.serverProtosPath = opts.serverProtos || (fs.existsSync(originServerPath) ? Constants.FILEPATH.SERVER_PROTOS : presentServerPath);
this.clientProtosPath = opts.clientProtos || (fs.existsSync(originClientPath) ? Constants.FILEPATH.CLIENT_PROTOS : presentClientPath);
this.setProtos(Constants.RESERVED.SERVER, path.join(app.getBase(), this.serverProtosPath));
this.setProtos(Constants.RESERVED.CLIENT, path.join(app.getBase(), this.clientProtosPath));
protobuf.init({
encoderProtos : this.serverProtos,
decoderProtos : this.clientProtos
});
}
encode(key, msg)
{
return protobuf.encode(key, msg);
}
encode2Bytes(key, msg)
{
return protobuf.encode2Bytes(key, msg);
}
decode(key, msg)
{
return protobuf.decode(key, msg);
}
getProtos()
{
return {
server : this.serverProtos,
client : this.clientProtos,
version : this.version
};
}
getVersion()
{
return this.version;
}
setProtos(type, path)
{
if (!fs.existsSync(path))
{
return;
}
if (type === Constants.RESERVED.SERVER)
{
this.serverProtos = protobuf.parse(require(path));
}
if (type === Constants.RESERVED.CLIENT)
{
this.clientProtos = protobuf.parse(require(path));
}
const protoStr = JSON.stringify(this.clientProtos) + JSON.stringify(this.serverProtos);
this.version = crypto.createHash('md5').update(protoStr).digest('base64');
// Watch file
const watcher = fs.watch(path, this.onUpdate.bind(this, type, path));
if (this.watchers[type])
{
this.watchers[type].close();
}
this.watchers[type] = watcher;
}
onUpdate(type, path, event)
{
if (event !== 'change')
{
return;
}
let data = null;
try {
data = fs.readFileSync(path, 'utf8');
}
catch (err)
{
logger.warn('change proto file error! path : %j', path);
logger.warn(err);
}
if (data != null)
{
const protos = protobuf.parse(JSON.parse(data));
if (type === Constants.RESERVED.SERVER)
{
protobuf.setEncoderProtos(protos);
this.serverProtos = protos;
}
else
{
protobuf.setDecoderProtos(protos);
this.clientProtos = protos;
}
const protoStr = JSON.stringify(this.clientProtos) + JSON.stringify(this.serverProtos);
this.version = crypto.createHash('md5').update(protoStr).digest('base64');
logger.info('change proto file , type : %j, path : %j, version : %j', type, path, this.version);
}
}
stop(force, cb)
{
for (const type in this.watchers)
{
this.watchers[type].close();
}
this.watchers = {};
process.nextTick(cb);
}
}
module.exports = function(app, opts)
{
return new ProtobuffComponent(app, opts);
};
ProtobuffComponent.prototype.name = '__protobuf__';