index.js
2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/**
* zookeeper client
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2016/10/12
*/
'use strict';
const zookeeper = require('node-zookeeper-client');
const _ = require('lodash');
const ONE_MONTH = 60 * 60 * 24 * 30;
const getter = (client, path, memory, cache) => {
client.getData(
path,
event => {
getter(client, path, memory, cache);
},
(err, data, stat) => {
if (err) {
console.log('Got path %s data error', path);
return;
}
let keys = path.replace(/^\/(pc|wap)\//, '').split('/');
if (keys.indexOf('json') > -1) { // /pc|wap/json/... is JSON string
try {
memory && _.set(memory, keys, JSON.parse(data.toString('utf8')));
} catch (e) {
console.log('%s catch: %s', e.message, path, data.toString('utf8'));
}
} else {
memory && _.set(memory, keys, data.toString('utf8') === 'true' ? true : false);
}
if (cache) {
cache.set('zookeeper:' + path, data.toString('utf8'), ONE_MONTH).catch(console.error);
console.log('cache %s data: %s', 'zookeeper:' + path, data.toString('utf8'));
}
console.log('%s data: %s', path, data.toString('utf8'));
}
)
};
// 遍历node path
const walkPath = (client, path, memory, cache) => {
client.getChildren(
path,
(err, children, stat) => {
if (err) {
console.log('Failed to list children of %s due to: %s', path, err);
return;
}
if (children.length === 0) {
// watch the path
getter(client, path, memory, cache);
} else {
_.forEach(children, child => {
walkPath(client, `${path}/${child}`, memory, cache);
});
}
}
)
};
module.exports = (server, host, memory, cache, extra = {}) => {
let client = zookeeper.createClient(server, {
spinDelay: 1000,
retries: 10
});
client.state = Symbol();
host = (host && _.indexOf(['pc', 'wap'], host) >= 0) ? host : 'wap';
client.on('connected', () => {
walkPath(client, `/${host}`, memory, cache)
});
client.on('state', state => {
if (!extra || !extra.onerror) {
return;
}
switch (state) {
case zookeeper.State.DISCONNECTED:
case zookeeper.State.EXPIRED:
case zookeeper.State.AUTH_FAILED:
extra.onerror({...state});
break;
default:
return;
}
});
client.connect();
};