Merge pull request #961 from bbassie/feature/instance-host-broadcast

Deliver broadcasts to all hosts, not just the local one
This commit is contained in:
Cooldude2606 authored and GitHub committed 2026-08-08 23:51:48 +01:00
commit c0138c3fe0
4 files changed
+53 -2

No files matched your search

+6
View File
@@ -183,6 +183,12 @@ export class HostRouter {
if (this.host !== origin && (!plugin || this.host.serverPlugins.has(plugin))) {
this.host.connector.forward(message);
}
} else if (dst.id === lib.Address.host) {
// Sent up to the controller, which passes it on to the other
// hosts. Nothing left to do when it came from there.
if (this.host !== origin && (!plugin || this.host.serverPlugins.has(plugin))) {
this.host.connector.forward(message);
}
} else if (dst.id === lib.Address.control) {
if (this.host !== origin) {
if (!plugin || this.host.serverPlugins.has(plugin)) {
+10
View File
@@ -225,6 +225,16 @@ export class Link {
return;
}
// A broadcast is addressed to every link of the type it targets, so
// being addressed to this one does not mean it stops here.
if (
message.type === "event"
&& message.dst.type === libData.Address.broadcast
&& this.router
) {
this._routeMessage(message, entry);
}
if (message.type === "request") {
this._processRequest(
message as libData.MessageRequest,
-2
View File
@@ -235,8 +235,6 @@ describe("Integration of link routing", function() {
};
for (const dstName of dsts[dst]) {
if (srcName === dstName) { continue; }
// TODO remove when broadcasting from instance to hosts is fixed, see #575
if (srcName === "instanceA1" && dstName === "hostB") { continue; }
let called;
handle(get(dstName), Event, async () => { called = true; });
const should = canReach(dstName);
+37
View File
@@ -486,6 +486,7 @@ describe("lib/link/link", function() {
{ message: "Unhandled message type invalid" }
);
});
it("should throw on Event failing validation", function() {
class StringEvent {
static type = "event";
@@ -502,6 +503,42 @@ describe("lib/link/link", function() {
{ message: "Event StringEvent failed validation" }
);
});
describe("Broadcast handling", function() {
// A broadcast is addressed to every link of the type it targets,
// so a link it reaches has to pass it on as well as handle it,
// see #575.
function mockRouter(record) {
return { forwardMessage: () => { record.routed = true; return true; } };
}
it("should route a broadcast addressed to this link as well as handle it", function() {
const record = {};
let handled = false;
testLink.router = mockRouter(record);
testLink.handle(SimpleEvent, async () => { handled = true; });
testConnector.emit("message", new lib.MessageEvent(1, dst, addr("allControls"), "SimpleEvent"));
assert(record.routed, "broadcast was not routed onwards");
assert(handled, "broadcast was not handled locally");
});
it("should handle a broadcast on a link which does not route", function() {
// Instances have no router, so routing unconditionally would
// throw here and the event would never be handled.
let handled = false;
testLink.handle(SimpleEvent, async () => { handled = true; });
testConnector.emit("message", new lib.MessageEvent(1, dst, addr("allControls"), "SimpleEvent"));
assert(handled, "broadcast was not handled locally");
});
it("should not route a non broadcast addressed to this link", function() {
const record = {};
testLink.router = mockRouter(record);
testLink.handle(SimpleEvent, async () => {});
testConnector.emit("message", new lib.MessageEvent(1, dst, src, "SimpleEvent"));
assert(!record.routed, "message addressed to this link was routed onwards");
});
});
});
describe(".forwardRequest()", function() {