Skip to content

Commit 9806cf2

Browse files
committed
wip
1 parent 76a1878 commit 9806cf2

File tree

3 files changed

+75
-7
lines changed

3 files changed

+75
-7
lines changed

app.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ srf.use('options', [
259259
srf.register(require('./lib/register')({logger}));
260260
srf.options(require('./lib/options')({srf, logger}));
261261

262+
// Start CLI runtime config server with access to srf.locals
263+
require('./lib/cli/runtime-config').initialize(srf.locals);
264+
262265
setInterval(async() => {
263266
const count = await srf.locals.registrar.getCountOfUsers();
264267
debug(`count of registered users: ${count}`);

lib/cli/cli.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,20 @@ async function handleFeatureServerCommand(args) {
8585
}
8686
break;
8787

88+
case 'active':
89+
const active = await sendCommand('fs-available');
90+
if (active.error || !active.success) {
91+
console.error('Error:', active.error || 'Failed to get active servers');
92+
process.exit(1);
93+
}
94+
if (active.available.length === 0) {
95+
console.log('No active feature servers found');
96+
} else {
97+
console.log('Available feature servers:');
98+
active.available.forEach((s) => console.log(` 🟢 ${s}`));
99+
}
100+
break;
101+
88102
case 'list':
89103
const list = await sendCommand('fs-list');
90104
if (list.error) {
@@ -108,7 +122,7 @@ async function handleFeatureServerCommand(args) {
108122

109123
default:
110124
console.error('Unknown command:', cmd);
111-
console.error('Use: drain, undrain, drained, list');
125+
console.error('Use: drain, undrain, drained, active, list');
112126
process.exit(1);
113127
}
114128
}
@@ -121,7 +135,8 @@ async function main() {
121135
console.log(' sbc-cli fs drain <ip> Drain server by IP');
122136
console.log(' sbc-cli fs undrain <ip> Undrain server by IP');
123137
console.log(' sbc-cli fs drained List drained server IPs');
124-
console.log(' sbc-cli fs list List all servers');
138+
console.log(' sbc-cli fs active List active/available servers');
139+
console.log(' sbc-cli fs list List all servers with status');
125140
console.log(' sbc-cli set <key> <value> Set config');
126141
console.log(' sbc-cli get <key> Get config');
127142
console.log(' sbc-cli list List all config');
@@ -130,6 +145,7 @@ async function main() {
130145
console.log(' sbc-cli fs drain 192.168.1.10');
131146
console.log(' sbc-cli fs undrain 192.168.1.10');
132147
console.log(' sbc-cli fs drained');
148+
console.log(' sbc-cli fs active');
133149
return;
134150
}
135151

@@ -139,7 +155,7 @@ async function main() {
139155
switch (cmd) {
140156
case 'fs':
141157
if (args.length < 2) {
142-
console.error('fs needs: drain, undrain, drained, or list');
158+
console.error('fs needs: drain, undrain, drained, active, or list');
143159
process.exit(1);
144160
}
145161
await handleFeatureServerCommand(args.slice(1));

lib/cli/runtime-config.js

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ async function processQueue() {
3131
}
3232

3333
class RuntimeConfig {
34-
constructor() {
34+
constructor(srfLocals = null) {
3535
this.server = null;
3636
this.socketPath = process.env.SBC_SOCKET_PATH || '/tmp/sbc-sip-sidecar.sock';
37+
this.srfLocals = srfLocals;
3738
this.startServer();
3839
}
3940

@@ -99,6 +100,25 @@ class RuntimeConfig {
99100
return runOperation(() => Object.fromEntries(config));
100101
}
101102

103+
async getAvailableFeatureServers() {
104+
return runOperation(async() => {
105+
if (!this.srfLocals || !this.srfLocals.retrieveSet) {
106+
return { error: 'Redis connection not available' };
107+
}
108+
109+
const JAMBONES_CLUSTER_ID = process.env.JAMBONES_CLUSTER_ID;
110+
const setNameFs = `${(JAMBONES_CLUSTER_ID || 'default')}:active-fs`;
111+
112+
try {
113+
const activeServers = await this.srfLocals.retrieveSet(setNameFs);
114+
return { activeServers: activeServers || [] };
115+
} catch (err) {
116+
logger.error({ err }, 'Error retrieving active feature servers');
117+
return { error: 'Failed to retrieve active feature servers' };
118+
}
119+
});
120+
}
121+
102122
startServer() {
103123
try {
104124
require('fs').unlinkSync(this.socketPath);
@@ -232,6 +252,21 @@ class RuntimeConfig {
232252
socket.write(JSON.stringify({ success: true, config: allConfig }) + '\n');
233253
break;
234254

255+
case 'fs-available':
256+
const availableResult = await this.getAvailableFeatureServers();
257+
if (availableResult.error) {
258+
socket.write(JSON.stringify({
259+
success: false,
260+
error: availableResult.error
261+
}) + '\n');
262+
} else {
263+
socket.write(JSON.stringify({
264+
success: true,
265+
available: availableResult.activeServers
266+
}) + '\n');
267+
}
268+
break;
269+
235270
default:
236271
socket.write(JSON.stringify({ error: 'Unknown action' }) + '\n');
237272
}
@@ -253,9 +288,23 @@ class RuntimeConfig {
253288
}
254289
}
255290

256-
const runtimeConfig = new RuntimeConfig();
291+
let runtimeConfig = null;
257292

258-
process.on('SIGINT', () => runtimeConfig.shutdown());
259-
process.on('SIGTERM', () => runtimeConfig.shutdown());
293+
function initializeRuntimeConfig(srfLocals) {
294+
if (!runtimeConfig) {
295+
runtimeConfig = new RuntimeConfig(srfLocals);
296+
process.on('SIGINT', () => runtimeConfig.shutdown());
297+
process.on('SIGTERM', () => runtimeConfig.shutdown());
298+
}
299+
return runtimeConfig;
300+
}
301+
302+
// For backward compatibility - create without srfLocals if imported directly
303+
if (!runtimeConfig) {
304+
runtimeConfig = new RuntimeConfig();
305+
process.on('SIGINT', () => runtimeConfig.shutdown());
306+
process.on('SIGTERM', () => runtimeConfig.shutdown());
307+
}
260308

261309
module.exports = runtimeConfig;
310+
module.exports.initialize = initializeRuntimeConfig;

0 commit comments

Comments
 (0)