*Initial version of syncProtomux api protocol that will keep Protomux channel/message tracking in sync between workers
This commit is contained in:
parent
2f30b743f6
commit
053e309d98
|
@ -14,14 +14,17 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lumeweb/hyperswarm-web": "git+https://git.lumeweb.com/LumeWeb/hyperswarm-web.git",
|
"@lumeweb/hyperswarm-web": "git+https://git.lumeweb.com/LumeWeb/hyperswarm-web.git",
|
||||||
|
"@lumeweb/rpc": "git+https://git.lumeweb.com/LumeWeb/rpc.git",
|
||||||
"@noble/ed25519": "^1.7.3",
|
"@noble/ed25519": "^1.7.3",
|
||||||
"@peculiar/webcrypto": "git+https://git.lumeweb.com/LumeWeb/webcrypto.git",
|
"@peculiar/webcrypto": "git+https://git.lumeweb.com/LumeWeb/webcrypto.git",
|
||||||
|
"async-mutex": "^0.4.0",
|
||||||
"b4a": "^1.6.3",
|
"b4a": "^1.6.3",
|
||||||
"eventemitter2": "^6.4.9",
|
"eventemitter2": "^6.4.9",
|
||||||
"hyperswarm": "^4.4.0",
|
"hyperswarm": "^4.4.0",
|
||||||
"libkmodule": "^0.2.53",
|
"libkmodule": "^0.2.53",
|
||||||
"libskynet": "^0.0.62",
|
"libskynet": "^0.0.62",
|
||||||
"noise-handshake": "^3.0.2",
|
"noise-handshake": "^3.0.2",
|
||||||
|
"protomux": "^3.4.1",
|
||||||
"randombytes": "github:LumeWeb/randombytes-browser"
|
"randombytes": "github:LumeWeb/randombytes-browser"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
69
src/index.ts
69
src/index.ts
|
@ -9,6 +9,9 @@ import b4a from "b4a";
|
||||||
import { pubKeyToIpv6 } from "./addr.js";
|
import { pubKeyToIpv6 } from "./addr.js";
|
||||||
import { EventEmitter2 as EventEmitter } from "eventemitter2";
|
import { EventEmitter2 as EventEmitter } from "eventemitter2";
|
||||||
import { logErr } from "libkmodule/dist";
|
import { logErr } from "libkmodule/dist";
|
||||||
|
// @ts-ignore
|
||||||
|
import Protomux from "protomux";
|
||||||
|
import { Mutex } from "async-mutex";
|
||||||
|
|
||||||
const MAX_PEER_LISTENERS = 20;
|
const MAX_PEER_LISTENERS = 20;
|
||||||
|
|
||||||
|
@ -68,6 +71,9 @@ addHandler("socketListenEvent", handleSocketListenEvent, {
|
||||||
});
|
});
|
||||||
addHandler("socketWrite", handleWriteSocketEvent);
|
addHandler("socketWrite", handleWriteSocketEvent);
|
||||||
addHandler("socketClose", handleCloseSocketEvent);
|
addHandler("socketClose", handleCloseSocketEvent);
|
||||||
|
addHandler("syncProtomux", handleSyncProtomux, {
|
||||||
|
receiveUpdates: true,
|
||||||
|
});
|
||||||
async function handlePresentSeed(aq: ActiveQuery) {
|
async function handlePresentSeed(aq: ActiveQuery) {
|
||||||
const pubkey = await ed.getPublicKey(aq.callerInput.rootKey);
|
const pubkey = await ed.getPublicKey(aq.callerInput.rootKey);
|
||||||
handlePresentSeedModule({
|
handlePresentSeedModule({
|
||||||
|
@ -392,6 +398,69 @@ async function handleGetSocketInfo(aq: ActiveQuery) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleSyncProtomux(aq: ActiveQuery) {
|
||||||
|
const socket = validateConnection(aq);
|
||||||
|
|
||||||
|
if (!socket) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mux = Protomux.from(socket);
|
||||||
|
const mutex: Mutex = mux.mutex ?? new Mutex();
|
||||||
|
if (!mux.mutex) {
|
||||||
|
mux.mutex = mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.once("close", () => {
|
||||||
|
socket.off("syncProtomux", sync);
|
||||||
|
aq.respond();
|
||||||
|
});
|
||||||
|
|
||||||
|
const send = (mux: any) => {
|
||||||
|
aq.sendUpdate({
|
||||||
|
remote: Object.keys(mux._remote),
|
||||||
|
local: Object.keys(mux._local),
|
||||||
|
free: mux._free,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const sync = () => send(mux);
|
||||||
|
|
||||||
|
mux.syncState = send.bind(undefined, mux);
|
||||||
|
|
||||||
|
sync();
|
||||||
|
|
||||||
|
socket.on("syncProtomux", sync);
|
||||||
|
|
||||||
|
aq.setReceiveUpdate?.(async (data: any) => {
|
||||||
|
await mutex.acquire();
|
||||||
|
|
||||||
|
["remote", "local"].forEach((field) => {
|
||||||
|
const rField = `_${field}`;
|
||||||
|
data[field].forEach((item: any) => {
|
||||||
|
if (!mux[rField][item]) {
|
||||||
|
while (item > mux[rField].length) {
|
||||||
|
mux[rField].push(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!mux[rField][item]) {
|
||||||
|
mux[rField][item] = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
data.free.forEach((index: number) => {
|
||||||
|
if (mux._free[index] === null) {
|
||||||
|
mux._free[index] = undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mux._free = mux._free.filter((item: any) => item !== undefined);
|
||||||
|
socket.emit("syncProtomux");
|
||||||
|
|
||||||
|
mutex.release();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getSwarmToSocketConnectionId(socket: any) {
|
function getSwarmToSocketConnectionId(socket: any) {
|
||||||
for (const conn of connections) {
|
for (const conn of connections) {
|
||||||
if (conn[1].conn === socket) {
|
if (conn[1].conn === socket) {
|
||||||
|
|
Loading…
Reference in New Issue