tm-sdk
Version:
tenmove copyright, node base module
314 lines (261 loc) • 7.93 kB
JavaScript
var zookeeper = require('node-zookeeper-client');
var events = require("events");
var logger = require("./logger").getLogger('');
var fs = require('fs');
// 节点类型
var NodeType = {
// 平台
Platform: 1,
// 服务器信息列表
ServerList: 2,
// 服务器节点
ServerNode: 3,
// 大区列表
ZoneList: 4,
// 大区节点
ZoneNode: 5
}
function Serverlist() {
// 事件管理
this.event_system = new events.EventEmitter();
// zookeeper连接
this.zk_client = null;
// zookeeper根路径
this.zk_root_path = "";
// zookeeper各个路径信息
this.zk_node_info = {}
// 所有服务器(id为key)
this.servers = {};
// 所有大区
this.zones = {};
};
// 通过文件加载服务器列表
Serverlist.prototype.initByFile = function(serverlist_file, zone_file) {
try {
var data = fs.readFileSync(serverlist_file, "UTF-8");
var servers = JSON.parse(data);
if(servers == null) {
logger.error("invalid serverlist file: %s", serverlist_file);
return false;
}
for(id in servers) {
this.addServer(servers[id]);
}
} catch(err) {
logger.error("read %s failed, err:%s", serverlist_file, err.toString());
return false;
}
if(zone_file == null) {
return true;
}
try {
var data = fs.readFileSync(zone_file, "UTF-8");
var zones = JSON.parse(data);
if(zones == null) {
logger.error("invalid zone file: %s", zone_file);
return false;
}
this.zones = zones;
for(id in zones) {
this.addZone(zones[id]);
}
} catch(err) {
logger.error("read %s failed, err:%s", zone_file, err.toString());
return false;
}
}
// 通过zookeeper加载服务器列表
Serverlist.prototype.initByZookeeper = function(zk_addr, path) {
this.zk_client = zookeeper.createClient(zk_addr);
this.zk_root_path = path;
this.zk_client.once('connected', function (err) {
if(err) {
return logger.error("connect to %s failed, error:%s", zk_addr, err);
}
logger.info('connected to zookeeper success.');
listNodes(mgr.zk_client, path);
});
this.zk_client.connect();
}
// 服务器列表相关
// 添加服务器
Serverlist.prototype.addServer = function(server) {
var id = server.id;
var oldServer = this.getServerByID(id);
if(oldServer == null) {
this.servers[id] = server;
// 抛出事件
this.emit("server_add", id, server);
} else {
// 如果已经有了,跟原有的比较
if(JSON.stringify(oldServer) == JSON.stringify(server)) {
return;
}
this.servers[id] = server;
// 抛出事件
this.emit("server_update", id, server);
}
}
// 删除服务器
Serverlist.prototype.deleteServer = function(id) {
var server = this.getServerByID(id);
if(server == null) {
return;
}
delete this.servers[id];
// 抛出事件
this.emit("server_del", id, server);
}
// 获取服务器信息
Serverlist.prototype.getServerByID = function(id) {
return this.servers[id];
}
// 获取所有服务器信息
Serverlist.prototype.getAllServer = function() {
return this.servers;
}
// 大区相关
// 添加大区
Serverlist.prototype.addZone = function(zone) {
var id = zone.id;
var oldZone = this.getZoneByID(id);
if(oldZone == null) {
this.zones[id] = zone;
// 抛出事件
this.emit("zone_add", id, zone);
} else {
// 如果已经有了,跟原有的比较
if(JSON.stringify(oldZone) == JSON.stringify(zone)) {
return;
}
this.zones[id] = zone;
// 抛出事件
this.emit("zone_update", id, zone);
}
}
// 删除大区
Serverlist.prototype.deleteZone = function(id) {
var zone = this.getZoneByID(id);
if(zone == null) {
return;
}
delete this.zones[id];
// 抛出事件
this.emit("zone_del", id, zone);
}
// 获取大区信息
Serverlist.prototype.getZoneByID = function(id) {
return this.zones[id];
}
// 获取所有服务器信息
Serverlist.prototype.getAllZone = function() {
return this.zones;
}
// 事件相关
// 触发事件
Serverlist.prototype.emit = function(event_name, ...args) {
this.event_system.emit(event_name, ...args);
}
// 注册事件监听器(永久)
Serverlist.prototype.on = function(event_name, listener) {
if(listener == null) {
return;
}
this.event_system.on(event_name, listener);
}
// 注册事件监听器(一次)
Serverlist.prototype.once = function(event_name, listener) {
if(listener == null) {
return;
}
this.event_system.once(event_name, listener);
}
// zookeeper相关
Serverlist.prototype.saveZkNodeInfo = function(path, type, id) {
this.zk_node_info[path] = {
type : type,
id : id
};
}
Serverlist.prototype.getZkNodeInfo = function(path) {
if(path in this.zk_node_info) {
return this.zk_node_info[path];
} else {
return null;
}
}
Serverlist.prototype.onZkNodeEvent = function(path, event) {
if(event.name == "NODE_DELETED") {
return mgr.onZkNodeDeleted(path);
}
mgr.onZkNodeChanged(path);
}
Serverlist.prototype.onZkNodeDeleted = function(path) {
var node = this.getZkNodeInfo(path);
if(node == null) {
return logger.error("invalid node:%s deleted.", path);
}
delete this.zk_node_info[path];
if(node.type == NodeType.ServerNode) {
// 删除服务器节点
this.deleteServer(node.id);
} else if(node.type == NodeType.ZoneNode) {
// 删除区节点
this.deleteZone(node.id);
}
}
Serverlist.prototype.getNode = function(client, path) {
client.getData(path,
function(event) {
if(event.name == "NODE_DELETED") {
return mgr.onZkNodeDeleted(path);
}
mgr.getNode(client, path);
},
function(err, data, stat) {
if(err) {
return logger.error(err);
}
var str = data.toString();
try {
var obj = JSON.parse(str);
} catch(e) {
return logger.error("parse path:%s's data:%s failed,%s", path, str, e.toString());
}
if(obj.type == NodeType.ZoneNode) {
mgr.saveZkNodeInfo(path, obj.type, obj.data.id);
mgr.addZone(obj.data);
} else if(obj.type == NodeType.ServerNode) {
mgr.saveZkNodeInfo(path, obj.type, obj.data.id);
mgr.addServer(obj.data);
}
}
);
}
function listNodes(client, path) {
mgr.getNode(client, path);
client.getChildren(
path,
function (event) {
if(event.name == "NODE_DELETED") {
return;//mgr.onZkNodeDeleted(path);
}
listNodes(client, path);
},
function (error, children, stat) {
if (error) {
return logger.info('Failed to list children of %s due to: %s.', path, error);
}
for(var i = 0; i < children.length; i++) {
listNodes(client, path + '/' + children[i]);
}
}
);
}
var mgr = null;
module.exports = function() {
if(mgr == null) {
mgr = new Serverlist();
}
return mgr;
}();