Updates
This commit is contained in:
+2
-2
@@ -116,8 +116,8 @@ MASTER_MAX_RECONNECT_ATTEMPTS=10
|
||||
MASTER_PROACTIVE_INVITE_DELAY=2000
|
||||
# Timeout for Autopass createInvite including member.flushed() (default: 20000ms)
|
||||
# CREATE_INVITE_TIMEOUT_MS=20000
|
||||
# Brief delay before Autobase replicate on new peer connections (default: 500ms)
|
||||
MASTER_REPLICATE_DELAY=500
|
||||
# Autopass replication is handled by Autopass's own swarm; p2ns topic does not replicate dnsPass
|
||||
# MASTER_REPLICATE_DELAY is intentionally unused for dnsPass replication.
|
||||
# Gap between serialized Autopass ops in ms (default: 50)
|
||||
# DNS_PASS_OP_GAP_MS=50
|
||||
|
||||
|
||||
@@ -49,6 +49,24 @@ async function ensureDnsPassOpen(pass) {
|
||||
return true;
|
||||
}
|
||||
|
||||
async function waitForAutobaseIdle(pass, timeoutMs = 5000) {
|
||||
const base = pass && pass.base;
|
||||
if (!base) return false;
|
||||
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeoutMs) {
|
||||
const flushing = typeof base._flushing === 'number' ? base._flushing > 0 : false;
|
||||
const fastForwarding = typeof base.isFastForwarding === 'function' ? base.isFastForwarding() : false;
|
||||
if (!base.updating && !base.appending && !flushing && !fastForwarding && !base.closing) {
|
||||
return true;
|
||||
}
|
||||
await sleep(100);
|
||||
}
|
||||
|
||||
logWarn('DnsPassQueue', 'Autobase did not become idle before dnsPass operation; proceeding cautiously');
|
||||
return false;
|
||||
}
|
||||
|
||||
function enqueueDnsPass(operation) {
|
||||
const run = chain.then(async () => {
|
||||
state.dnsPassWriteInProgress = (state.dnsPassWriteInProgress || 0) + 1;
|
||||
@@ -82,6 +100,7 @@ async function createInvite(pass, opts) {
|
||||
if (!(await ensureDnsPassOpen(pass))) {
|
||||
throw new Error('dnsPass not open');
|
||||
}
|
||||
await waitForAutobaseIdle(pass);
|
||||
logDebug('DnsPassQueue', 'createInvite: starting');
|
||||
try {
|
||||
return await withTimeout(
|
||||
|
||||
@@ -356,38 +356,14 @@ async function main() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Replicate Autopass via Autobase (base.replicate), not Corestore.replicate on every core.
|
||||
* Autopass itself uses base.replicate(connection) — store.replicate races createInvite and
|
||||
* can leave cores in SESSION_CLOSED / "Corestore is closed" states.
|
||||
* Do not replicate the Autopass/Corestore state over the p2ns topic connection.
|
||||
* Autopass owns replication through its own BlindPairing/Hyperswarm discovery flow.
|
||||
* Replicating the Autopass base here races createInvite() and can leave HyperDB's
|
||||
* atomic view mid-flush ("Atomic state must flush to parent").
|
||||
*/
|
||||
function scheduleConnectionReplication(conn) {
|
||||
if (!conn || conn.destroyed) return;
|
||||
|
||||
const runReplicate = () => {
|
||||
if (conn.destroyed) return;
|
||||
if (state.dnsPassWriteInProgress > 0) {
|
||||
setTimeout(runReplicate, 150);
|
||||
return;
|
||||
}
|
||||
const pass = getDnsPass();
|
||||
if (!pass?.base || pass.base.closed) {
|
||||
logDebug('Swarm', 'Skipping Autobase replicate — dnsPass not ready yet');
|
||||
return;
|
||||
}
|
||||
if (store.closing) {
|
||||
logWarn('Swarm', 'Skipping Autobase replicate — corestore is closing');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
pass.base.replicate(conn, { live: true });
|
||||
logDebug('Swarm', 'Autobase replication started for connection');
|
||||
} catch (err) {
|
||||
logWarn('Swarm', `base.replicate failed: ${err.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
const delayMs = parseInt(process.env.MASTER_REPLICATE_DELAY || '500', 10);
|
||||
setTimeout(runReplicate, delayMs);
|
||||
logDebug('Swarm', 'Skipping p2ns-topic Autopass replication; Autopass swarm handles it');
|
||||
}
|
||||
|
||||
// Helper function to safely set dnsPass and ensure state consistency
|
||||
|
||||
Reference in New Issue
Block a user