telemersive-bus 0.6.14 → 0.6.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/BusManager.js +80 -54
- package/package.json +1 -1
package/lib/BusManager.js
CHANGED
|
@@ -32,6 +32,10 @@ class BusManager {
|
|
|
32
32
|
this.roomHousekeep = {};
|
|
33
33
|
this.houseKeepingInProgress = false;
|
|
34
34
|
this.housekeepingId = 0;
|
|
35
|
+
// promise set while cleanOut is actively mutating this.rooms, null otherwise.
|
|
36
|
+
// startHousekeeping awaits it before snapshotting this.rooms, so a new cycle
|
|
37
|
+
// cannot start before the previous one's room deletions have fully settled.
|
|
38
|
+
this.cleanOutInProgress = null;
|
|
35
39
|
this.chatManagers = {};
|
|
36
40
|
this.switchBoardURI = null;
|
|
37
41
|
}
|
|
@@ -120,6 +124,12 @@ class BusManager {
|
|
|
120
124
|
* when peer leaves a room
|
|
121
125
|
*/
|
|
122
126
|
startHousekeeping = async () => {
|
|
127
|
+
// wait for any in-flight cleanOut to fully settle before snapshotting this.rooms.
|
|
128
|
+
// this prevents overlap where a still-running cleanOut's slow stopServerSidePortScripts
|
|
129
|
+
// finishes (and deletes from this.rooms) after a new cycle already snapshotted them.
|
|
130
|
+
if (this.cleanOutInProgress) {
|
|
131
|
+
await this.cleanOutInProgress;
|
|
132
|
+
}
|
|
123
133
|
// we dont want to start another housekeeping process until the previous one has finished
|
|
124
134
|
if(!this.houseKeepingInProgress){
|
|
125
135
|
this.houseKeepingInProgress = true;
|
|
@@ -168,6 +178,8 @@ class BusManager {
|
|
|
168
178
|
console.log(` -> housekeeping -> pinging all rooms ...`);
|
|
169
179
|
const keys = Object.keys(this.rooms);
|
|
170
180
|
|
|
181
|
+
// clean up auto-generated subscriptions from prior cycles before subscribing again
|
|
182
|
+
await this.communicator.unsubscribe(this.busTopics.baseRoomAlivePing("+").build());
|
|
171
183
|
// subscribe to all room ping alive topic
|
|
172
184
|
await this.communicator.subscribe(new BusMsgSub(this.busTopics.baseRoomAlivePing("+").build(), this.onRoomAlive, PeerCredentials, 0));
|
|
173
185
|
|
|
@@ -266,62 +278,76 @@ class BusManager {
|
|
|
266
278
|
if (myId !== this.housekeepingId) {
|
|
267
279
|
return;
|
|
268
280
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
281
|
+
// expose the in-flight cleanOut as a promise so the next startHousekeeping can await it
|
|
282
|
+
// and avoid snapshotting this.rooms while deleteRoom is still mutating it.
|
|
283
|
+
this.cleanOutInProgress = (async () => {
|
|
284
|
+
try {
|
|
285
|
+
if(this.houseKeepingInProgress) {
|
|
286
|
+
console.log(` -> housekeeping -> cleaning out ...`);
|
|
287
|
+
// flag the room as being in the process to be removed. the entry may already have
|
|
288
|
+
// been deleted from this.rooms by an earlier overlapping cleanOut whose slow
|
|
289
|
+
// stopServerSidePortScripts only just finished — in that case, nothing to flag.
|
|
290
|
+
const flag4cleanupRooms = (currentRoom) => {
|
|
291
|
+
const room = this.rooms[currentRoom.roomName];
|
|
292
|
+
if (room) room.flagRoom4cleanup = true;
|
|
293
|
+
};
|
|
294
|
+
Object.values(this.roomHousekeep).forEach(flag4cleanupRooms);
|
|
295
|
+
|
|
296
|
+
// kick out the non-responding peers
|
|
297
|
+
const kickOutPeer = async (currentPeer) => {
|
|
298
|
+
console.log(` <- remove peer '${currentPeer.peerName}' from room '${currentPeer.roomName}' `);
|
|
299
|
+
// first we send clear retain message to peer joined addresses that have not replied:
|
|
300
|
+
await this.communicator.clearRetain(this.busTopics.roomPeerJoin(currentPeer.roomName, currentPeer.peerId).build());
|
|
301
|
+
|
|
302
|
+
// create the payload for the leave message
|
|
303
|
+
const infoPayload = {
|
|
304
|
+
timestamp: Math.round(new Date().getTime() / 1000),
|
|
305
|
+
peerId: currentPeer.peerId,
|
|
306
|
+
peerName: currentPeer.peerName,
|
|
307
|
+
roomName: currentPeer.roomName
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// sends the left message to all peers joined in the same room
|
|
311
|
+
await this.communicator.publish(
|
|
312
|
+
new BusMsgPub(
|
|
313
|
+
this.busTopics.roomPeerLeft(currentPeer.roomName, currentPeer.peerId).build(),
|
|
314
|
+
PeerInfo, 2, true).encode(infoPayload));
|
|
315
|
+
}
|
|
316
|
+
const peerCleanup = async () => {
|
|
317
|
+
for (const peer of Object.values(this.peerHousekeep)) {
|
|
318
|
+
await kickOutPeer(peer);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
await peerCleanup();
|
|
322
|
+
|
|
323
|
+
// And now remove the rooms
|
|
324
|
+
const cleanupRooms = async (currentRoom) => await this.deleteRoom(currentRoom.roomName);
|
|
325
|
+
const housekeeping = async () => {
|
|
326
|
+
for (const room of Object.values(this.roomHousekeep)) {
|
|
327
|
+
await cleanupRooms(room);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
await housekeeping();
|
|
331
|
+
|
|
332
|
+
console.log(` -> housekeeping DONE`);
|
|
333
|
+
} else {
|
|
334
|
+
console.log(` -> housekeeping was interrupted`);
|
|
307
335
|
}
|
|
308
|
-
};
|
|
309
|
-
await housekeeping();
|
|
310
|
-
|
|
311
|
-
console.log(` -> housekeeping DONE`);
|
|
312
|
-
} else {
|
|
313
|
-
console.log(` -> housekeeping was interrupted`);
|
|
314
|
-
}
|
|
315
336
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
337
|
+
// and we stop by unsubscribing to all peer info messages inside all rooms
|
|
338
|
+
await this.communicator.unsubscribe(this.busTopics.roomPeerJoin('+', '+').build());
|
|
339
|
+
// unsubscribing to all room ping alive topic
|
|
340
|
+
await this.communicator.unsubscribe(this.busTopics.baseRoomAlivePing("+").build());
|
|
341
|
+
// cleanup the communicator
|
|
342
|
+
this.communicator.clearAutoGeneratedSubscriptions();
|
|
343
|
+
// set this flag to false at the end to make sure a new houskeeping cycle can only be started once
|
|
344
|
+
// all topics are unsubscribed - otherwise it won't gather the joined peers inside the room.
|
|
345
|
+
this.houseKeepingInProgress = false;
|
|
346
|
+
} finally {
|
|
347
|
+
this.cleanOutInProgress = null;
|
|
348
|
+
}
|
|
349
|
+
})();
|
|
350
|
+
await this.cleanOutInProgress;
|
|
325
351
|
}
|
|
326
352
|
|
|
327
353
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "telemersive-bus",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.16",
|
|
4
4
|
"description": "MQTT based data protocol to manage unlimited peers, connected by rooms, where all peers joined to a room can exchange private data. It provides a simple chat mechanism, latency pinging, publish-subscribe mechanism (based on mqtt) and a OSC-like data stream. ",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|