Caching
This commit is contained in:
@@ -337,6 +337,7 @@ async function main() {
|
|||||||
let processingInvite = false;
|
let processingInvite = false;
|
||||||
let currentInvitePromise = null;
|
let currentInvitePromise = null;
|
||||||
let currentPairOperation = null; // Track active pairing operation for cleanup
|
let currentPairOperation = null; // Track active pairing operation for cleanup
|
||||||
|
let cachedMasterInviteWire = null;
|
||||||
|
|
||||||
// Helper function to safely get dnsPass and ensure state consistency
|
// Helper function to safely get dnsPass and ensure state consistency
|
||||||
function getDnsPass() {
|
function getDnsPass() {
|
||||||
@@ -382,6 +383,26 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function prepareMasterInvite(reason = 'startup') {
|
||||||
|
if (!isMaster) return null;
|
||||||
|
const pass = getDnsPass();
|
||||||
|
if (!pass) return null;
|
||||||
|
if (cachedMasterInviteWire) return cachedMasterInviteWire;
|
||||||
|
|
||||||
|
const { createInvite, inviteToWire, invitePreview } = require('./includes/core/dns-pass-queue');
|
||||||
|
logInfo('Swarm', `Preparing cached Autopass invite (${reason})...`);
|
||||||
|
const inv = await createInvite(pass);
|
||||||
|
cachedMasterInviteWire = inviteToWire(inv);
|
||||||
|
logInfo('Swarm', `Cached Autopass invite ready (${invitePreview(inv)})`);
|
||||||
|
return cachedMasterInviteWire;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearCachedMasterInvite(reason = 'unknown') {
|
||||||
|
if (!cachedMasterInviteWire) return;
|
||||||
|
cachedMasterInviteWire = null;
|
||||||
|
logDebug('Swarm', `Cleared cached Autopass invite (${reason})`);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper functions for invite processing mutex
|
// Helper functions for invite processing mutex
|
||||||
function isProcessingInvite() {
|
function isProcessingInvite() {
|
||||||
return processingInvite;
|
return processingInvite;
|
||||||
@@ -453,10 +474,10 @@ async function main() {
|
|||||||
logInfo('Swarm', `Processing pending invite request from ${peerId} (queued for ${Math.round(age/1000)}s)`);
|
logInfo('Swarm', `Processing pending invite request from ${peerId} (queued for ${Math.round(age/1000)}s)`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { createInvite, inviteToWire, invitePreview } = require('./includes/core/dns-pass-queue');
|
const invWire = await prepareMasterInvite(`pending request from ${peerId.substring(0, 16)}...`);
|
||||||
const inv = await createInvite(state.dnsPass);
|
if (!invWire) {
|
||||||
const invWire = inviteToWire(inv);
|
throw new Error('cached master invite unavailable');
|
||||||
logInfo('Swarm', `Created invite for pending request from ${peerId}: ${invitePreview(inv)}`);
|
}
|
||||||
const sent = channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
const sent = channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
||||||
if (sent) {
|
if (sent) {
|
||||||
logInfo('Swarm', `Successfully sent pending invite to ${peerId}`);
|
logInfo('Swarm', `Successfully sent pending invite to ${peerId}`);
|
||||||
@@ -780,6 +801,14 @@ async function main() {
|
|||||||
// Handle invite acknowledgment from joiner
|
// Handle invite acknowledgment from joiner
|
||||||
if (message === 'invite_ack') {
|
if (message === 'invite_ack') {
|
||||||
logInfo('Swarm', `Received invite_ack from peer ${peerId}`);
|
logInfo('Swarm', `Received invite_ack from peer ${peerId}`);
|
||||||
|
clearCachedMasterInvite(`ack from ${peerId.substring(0, 16)}...`);
|
||||||
|
if (isMaster) {
|
||||||
|
setTimeout(() => {
|
||||||
|
prepareMasterInvite('post-ack refresh').catch((err) => {
|
||||||
|
logWarn('Swarm', `Could not refresh cached invite after ack: ${err.message}`);
|
||||||
|
});
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
// Clear pending ack timeout for this peer
|
// Clear pending ack timeout for this peer
|
||||||
const pending = pendingInviteAcks.get(peerId);
|
const pending = pendingInviteAcks.get(peerId);
|
||||||
if (pending) {
|
if (pending) {
|
||||||
@@ -871,8 +900,7 @@ async function main() {
|
|||||||
channelManager.sendToPeer(CORE_DOMAIN, 'request', peerId, 'invite_unavailable:creation_failed');
|
channelManager.sendToPeer(CORE_DOMAIN, 'request', peerId, 'invite_unavailable:creation_failed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logInfo('Swarm', `Creating Autopass invite for peer ${peerId}...`);
|
logInfo('Swarm', `Sending cached Autopass invite to peer ${peerId}...`);
|
||||||
const { createInvite, inviteToWire, invitePreview } = require('./includes/core/dns-pass-queue');
|
|
||||||
const inviteChannelInfo = channelManager.getChannelInfo(CORE_DOMAIN, 'invite');
|
const inviteChannelInfo = channelManager.getChannelInfo(CORE_DOMAIN, 'invite');
|
||||||
const invitePeerChannel = inviteChannelInfo?.peerChannels?.get(peerId);
|
const invitePeerChannel = inviteChannelInfo?.peerChannels?.get(peerId);
|
||||||
if (invitePeerChannel) {
|
if (invitePeerChannel) {
|
||||||
@@ -881,9 +909,11 @@ async function main() {
|
|||||||
logWarn('Swarm', `Invite channel not fully open for ${peerId}, sending invite anyway (protomux may queue)`);
|
logWarn('Swarm', `Invite channel not fully open for ${peerId}, sending invite anyway (protomux may queue)`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const inv = await createInvite(pass);
|
const invWire = await prepareMasterInvite(`request from ${peerId.substring(0, 16)}...`);
|
||||||
const invWire = inviteToWire(inv);
|
if (!invWire) {
|
||||||
logInfo('Swarm', `Created invite for requesting peer ${peerId}: ${invitePreview(inv)}`);
|
throw new Error('cached master invite unavailable');
|
||||||
|
}
|
||||||
|
logInfo('Swarm', `Cached invite ready for requesting peer ${peerId}`);
|
||||||
try {
|
try {
|
||||||
const sent = channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
const sent = channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
||||||
if (!sent) {
|
if (!sent) {
|
||||||
@@ -921,14 +951,15 @@ async function main() {
|
|||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
const retryPass = getDnsPass();
|
const retryPass = getDnsPass();
|
||||||
const { isDnsPassUsable } = require('./includes/core/core');
|
const { isDnsPassUsable } = require('./includes/core/core');
|
||||||
const { createInvite, inviteToWire, whenDnsPassIdle, ensureDnsPassOpen } = require('./includes/core/dns-pass-queue');
|
const { whenDnsPassIdle, ensureDnsPassOpen } = require('./includes/core/dns-pass-queue');
|
||||||
if (!connectedPeers.has(peerId) || !retryPass) return;
|
if (!connectedPeers.has(peerId) || !retryPass) return;
|
||||||
await whenDnsPassIdle();
|
await whenDnsPassIdle();
|
||||||
await ensureDnsPassOpen(retryPass);
|
await ensureDnsPassOpen(retryPass);
|
||||||
if (!isDnsPassUsable(retryPass)) return;
|
if (!isDnsPassUsable(retryPass)) return;
|
||||||
try {
|
try {
|
||||||
const inv = await createInvite(retryPass);
|
const invWire = await prepareMasterInvite(`retry for ${peerId.substring(0, 16)}...`);
|
||||||
channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, inviteToWire(inv));
|
if (!invWire) return;
|
||||||
|
channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
||||||
logInfo('Swarm', `Sent invite to ${peerId} after dnsPass busy retry`);
|
logInfo('Swarm', `Sent invite to ${peerId} after dnsPass busy retry`);
|
||||||
} catch (retryErr) {
|
} catch (retryErr) {
|
||||||
logWarn('Swarm', `Invite retry failed for ${peerId}: ${retryErr.message}`);
|
logWarn('Swarm', `Invite retry failed for ${peerId}: ${retryErr.message}`);
|
||||||
@@ -964,10 +995,14 @@ async function main() {
|
|||||||
if (pass && isDnsPassUsable(pass) && (isMaster || process.env.ALLOW_ANY_WRITER_INVITES === 'true')) {
|
if (pass && isDnsPassUsable(pass) && (isMaster || process.env.ALLOW_ANY_WRITER_INVITES === 'true')) {
|
||||||
// We can create an invite - send it back through the relay chain
|
// We can create an invite - send it back through the relay chain
|
||||||
try {
|
try {
|
||||||
const { createInvite, inviteToWire, whenDnsPassIdle } = require('./includes/core/dns-pass-queue');
|
const { whenDnsPassIdle } = require('./includes/core/dns-pass-queue');
|
||||||
await whenDnsPassIdle();
|
await whenDnsPassIdle();
|
||||||
const inv = await createInvite(pass);
|
const invWire = isMaster
|
||||||
const invWire = inviteToWire(inv);
|
? await prepareMasterInvite(`relay for ${originPeerId.substring(0, 16)}...`)
|
||||||
|
: null;
|
||||||
|
if (!invWire) {
|
||||||
|
throw new Error('cached relay invite unavailable');
|
||||||
|
}
|
||||||
logInfo('Swarm', `Created relay invite for origin ${originPeerId.substring(0, 16)}...`);
|
logInfo('Swarm', `Created relay invite for origin ${originPeerId.substring(0, 16)}...`);
|
||||||
channelManager.sendToPeer(CORE_DOMAIN, 'request', peerId, `relay_invite_response:${originPeerId}:${invWire}`);
|
channelManager.sendToPeer(CORE_DOMAIN, 'request', peerId, `relay_invite_response:${originPeerId}:${invWire}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -1310,10 +1345,11 @@ async function main() {
|
|||||||
pendingInviteAcks.delete(peerId);
|
pendingInviteAcks.delete(peerId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { createInvite, inviteToWire, invitePreview } = require('./includes/core/dns-pass-queue');
|
const invWire = await prepareMasterInvite(`proactive send to ${peerId.substring(0, 16)}...`);
|
||||||
const inv = await createInvite(pass);
|
if (!invWire) {
|
||||||
const invWire = inviteToWire(inv);
|
throw new Error('cached master invite unavailable');
|
||||||
logInfo('Swarm', `Created proactive invite for peer ${peerId} (attempt ${retryCount}/${maxRetries}): ${invitePreview(inv)}`);
|
}
|
||||||
|
logInfo('Swarm', `Using cached proactive invite for peer ${peerId} (attempt ${retryCount}/${maxRetries})`);
|
||||||
const success = channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
const success = channelManager.sendToPeer(CORE_DOMAIN, 'invite', peerId, invWire);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -1756,6 +1792,12 @@ async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logInfo('Main', `Core retrieved. Writable: ${core.writable}, Key: ${core.key.toString('hex')}`);
|
logInfo('Main', `Core retrieved. Writable: ${core.writable}, Key: ${core.key.toString('hex')}`);
|
||||||
|
try {
|
||||||
|
await prepareMasterInvite('master startup before p2ns swarm join');
|
||||||
|
} catch (err) {
|
||||||
|
logError('Main', `Failed to prepare initial Autopass invite before swarm join: ${err.message}`);
|
||||||
|
logError('Main', 'Restart with --clean --master if this persists; invite requests will fail until an invite can be cached.');
|
||||||
|
}
|
||||||
// Setup domains watcher for master
|
// Setup domains watcher for master
|
||||||
setupDomainsWatcher();
|
setupDomainsWatcher();
|
||||||
setupListeners();
|
setupListeners();
|
||||||
|
|||||||
Reference in New Issue
Block a user