-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
129 lines (107 loc) · 4.78 KB
/
index.js
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
'use strict';
var events = require('events');
var inherits = require('util').inherits;
var xtend = require('xtend');
var baseConfig = require('./base-config.js');
var cws = require('./consul-watch-store.js');
var cserv = require('./consul-services.js');
var prepareTags = require('./prepare-tags.js');
var fullfilledServices = require('./fullfilled-services.js');
var fullfilledLooseServices = require('./fullfilled-loose-services.js');
var hasServicesChanged = require('./has-services-changed.js');
var consulRegister = require('./consul-register.js');
module.exports = Magistrate;
Magistrate.prototype.service = consulRegister;
function Magistrate () {
if (!(this instanceof Magistrate)) return new Magistrate();
events.EventEmitter.call(this);
this._combined_config = this._service_config = this._base_config = baseConfig;
this._cluster_settings = {};
this._services = {};
this._cluster_settings_populated;
this._service_config_populated;
this._services_populated;
this._ready_sent;
var self = this;
process.nextTick(function () { self.setConfiguration(); });
}
inherits(Magistrate, events.EventEmitter);
Magistrate.prototype.setConfiguration = function setConfiguration () {
console.log('[magistrate] Set configuration');
if (!this._base_config.consul) {
var exec = process.env.EXEC;
if (!exec) throw new Error('An executable is missing! Set env variable EXEC or CONSUL');
this._service_config_populated = true;
if (this._base_config.services && this._base_config.services.length && !fullfilledServices(this._base_config)) {
console.log('[magistrate] No consul, no service discovery, missing services:', this._base_config.services);
// todo : better handling of missing services, (fallback to local_config).
this._services_populated = false;
} else {
this._services_populated = true;
}
this.settings(null, { exec: exec });
} else {
cws(kvPrefix('cluster_settings', this._base_config), this.settings.bind(this));
cws(kvPrefix('service_config', this._base_config), this.config.bind(this));
cserv(this._base_config, this.services.bind(this));
}
};
function kvPrefix (name, config) {
return [name, config.name, config.environment].join('/');
}
Magistrate.prototype.settings = function settings (err, data) {
if (err) {
if (err.clean_exit) {
console.log({ error: err }, 'Error receiving cluster settings');
return process.exit(0);
}
throw err;
}
this._cluster_settings = data;
if (process.env.CLUSTER_SIZE) this._cluster_settings.size = Number(process.env.CLUSTER_SIZE);
this._cluster_settings_populated = true;
this._emitChange(true);
return this._cluster_settings;
};
Magistrate.prototype.config = function config (err, data) {
if (err) {
if (err.clean_exit) {
console.log({ error: err }, 'Error receiving service config');
return process.exit(0);
}
throw err;
}
this._service_config = xtend(this._base_config, data);
// This is the only time we add tags from kv store, there is no special handling when tags appears via watching
this._service_config.tags = prepareTags(this._service_config);
this._combined_config = xtend(this._service_config, this._services);
this._combined_config.fullfilled_services = fullfilledServices(this._combined_config);
this._combined_config.fullfilled_loose_services = fullfilledLooseServices(this._combined_config);
this._service_config_populated = true;
this._emitChange(true);
return this._combined_config;
};
Magistrate.prototype.services = function services (err, data) {
if (err) return console.log({ error: err }, 'Error in service discovery');
console.log('[magistrate] Change in services:', data);
var restart = hasServicesChanged(this._combined_config, this._services, data);
this._services = data;
this._combined_config = xtend(this._service_config, this._services);
this._combined_config.fullfilled_services = fullfilledServices(this._combined_config);
this._combined_config.fullfilled_loose_services = fullfilledLooseServices(this._combined_config);
this._services_populated = this._services_populated || this._combined_config.fullfilled_services;
this._emitChange(restart);
return this._combined_config;
};
Magistrate.prototype.getConfig = function getConfig () {
return JSON.parse(JSON.stringify(this._combined_config));
};
Magistrate.prototype._emitChange = function _emitChange (recommendingRestart) {
var settings = JSON.parse(JSON.stringify(this._cluster_settings));
var config = JSON.parse(JSON.stringify(this._combined_config));
if (this._ready_sent) this.emit('change', settings, config, recommendingRestart);
if (!this._ready_sent && this._cluster_settings_populated && this._service_config_populated && this._services_populated) {
this._ready_sent = true;
this.emit('ready', settings, config);
}
};