Skip to content

Commit 214d6d3

Browse files
committed
added logging to debug downloads
Signed-off-by: Robert Gogete <[email protected]>
1 parent a3826f6 commit 214d6d3

File tree

3 files changed

+234
-208
lines changed

3 files changed

+234
-208
lines changed

examples/nat-tools-example.js

Lines changed: 117 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,46 @@ import crypto from 'crypto';
1717
// Configuration
1818
const CONFIG = {
1919
digDirectory: path.join(os.homedir(), '.dig'),
20-
discoveryIntervalMs: 30000, // 30 seconds
20+
discoveryIntervalMs: 30000, // 5 minutes
2121
peers: ['http://dig-relay-prod.eba-2cmanxbe.us-east-1.elasticbeanstalk.com/gun']
2222
};
2323

2424
// Track files currently being downloaded to prevent duplicates
2525
const downloadingFiles = new Set();
26+
const downloadQueue = []; // Queue for pending downloads
27+
let currentDownload = null; // Track current download
28+
29+
/**
30+
* Process the next download in the queue
31+
*/
32+
function processNextDownload(natTools) {
33+
// If already downloading or queue is empty, do nothing
34+
if (currentDownload !== null || downloadQueue.length === 0) {
35+
return;
36+
}
37+
38+
// Get the next download from the queue
39+
const { magnetUri, displayName, existingFiles } = downloadQueue.shift();
40+
currentDownload = magnetUri;
41+
downloadingFiles.add(magnetUri);
42+
43+
logger.info(`\n📥 Starting download: ${displayName} (${downloadQueue.length} remaining in queue)`);
44+
45+
// Fire-and-forget: just start the download
46+
// Events will be handled by the global listeners set up in main()
47+
natTools.downloadFromMagnet(magnetUri);
48+
}
49+
50+
/**
51+
* Add a download to the queue and start processing if not already downloading
52+
*/
53+
function queueDownload(natTools, magnetUri, displayName, existingFiles) {
54+
downloadQueue.push({ magnetUri, displayName, existingFiles });
55+
logger.info(`📋 Queued: ${displayName} (queue size: ${downloadQueue.length})`);
56+
57+
// Start processing if not already downloading
58+
processNextDownload(natTools);
59+
}
2660

2761
// Create a simple logger
2862
const logger = {
@@ -165,73 +199,38 @@ async function discoverAndDownload(natTools) {
165199
return;
166200
}
167201

168-
logger.info(`📥 Found ${newMagnetUris.length} new files to download`);
169-
170202
// Ensure download directory exists
171203
if (!fs.existsSync(CONFIG.digDirectory)) {
172204
fs.mkdirSync(CONFIG.digDirectory, { recursive: true });
173205
}
174206

175-
// Download new files
176-
for (const magnetUri of newMagnetUris) {
177-
try {
178-
// Extract display name from magnet URI (dn parameter) or use timestamp
179-
const displayNameMatch = magnetUri.match(/dn=([^&]+)/);
180-
const displayName = displayNameMatch ? decodeURIComponent(displayNameMatch[1]) : `file-${Date.now()}`;
181-
182-
// Check if already downloading
183-
if (downloadingFiles.has(magnetUri)) {
184-
logger.debug(`⏳ Already downloading: ${displayName}`);
185-
continue;
186-
}
187-
188-
// Mark as downloading
189-
downloadingFiles.add(magnetUri);
190-
191-
logger.info(`📥 Downloading: ${displayName}...`);
192-
193-
try {
194-
// Download the file
195-
const buffer = await natTools.downloadFromMagnet(magnetUri);
196-
197-
// Calculate hash of downloaded content
198-
const contentHash = crypto.createHash('sha256').update(buffer).digest('hex');
199-
200-
// Check if we already have this content
201-
if (existingFiles.has(contentHash)) {
202-
logger.info(`⏭️ Already have file with hash ${contentHash.substring(0, 16)}...`);
203-
downloadingFiles.delete(magnetUri);
204-
continue;
205-
}
206-
207-
// Save the file with the display name or content hash
208-
const fileName = displayName.endsWith('.dig') ? displayName : `${contentHash}.dig`;
209-
const filePath = path.join(CONFIG.digDirectory, fileName);
210-
fs.writeFileSync(filePath, buffer);
207+
logger.info(`📥 Found ${newMagnetUris.length} new files to download`);
208+
logger.info(`🔄 Adding to sequential download queue...`);
211209

212-
logger.info(`✅ Downloaded: ${fileName} (${buffer.length} bytes)`);
210+
// Create a set of magnet URIs already in the queue
211+
const queuedMagnetUris = new Set(downloadQueue.map(item => item.magnetUri));
213212

214-
// Add to existing files set
215-
existingFiles.add(contentHash);
213+
// Queue all new downloads
214+
let addedCount = 0;
215+
for (const magnetUri of newMagnetUris) {
216+
// Skip if already downloading, in queue, or we already have it seeded
217+
if (downloadingFiles.has(magnetUri) || queuedMagnetUris.has(magnetUri)) {
218+
continue;
219+
}
216220

217-
// Remove from downloading set
218-
downloadingFiles.delete(magnetUri);
221+
// Extract display name from magnet URI (dn parameter) or use timestamp
222+
const displayNameMatch = magnetUri.match(/dn=([^&]+)/);
223+
const displayName = displayNameMatch ? decodeURIComponent(displayNameMatch[1]) : `file-${Date.now()}`;
219224

220-
// Optionally seed the downloaded file
221-
try {
222-
await natTools.seedFile(filePath);
223-
logger.info(`🌱 Now seeding downloaded file: ${fileName}`);
224-
} catch (error) {
225-
logger.warn(`⚠️ Could not seed downloaded file:`, error.message);
226-
}
227-
} catch (downloadError) {
228-
downloadingFiles.delete(magnetUri);
229-
throw downloadError;
230-
}
225+
// Add to queue
226+
queueDownload(natTools, magnetUri, displayName, existingFiles);
227+
addedCount++;
228+
}
231229

232-
} catch (error) {
233-
logger.error(`❌ Failed to download file:`, error.message);
234-
}
230+
if (addedCount > 0) {
231+
logger.info(`✅ Added ${addedCount} new downloads to queue`);
232+
} else {
233+
logger.info(`ℹ️ No new downloads to add (all are already downloading or queued)`);
235234
}
236235

237236
} catch (error) {
@@ -264,10 +263,8 @@ async function main() {
264263
await natTools.initialize();
265264
logger.info('✅ NAT Tools initialized');
266265

267-
// Set up download progress tracking
268-
let currentDownload = null;
266+
// Set up download event handlers
269267
webTorrentManager.on('metadata', (data) => {
270-
currentDownload = data.name;
271268
logger.info(`📋 Metadata received: ${data.name} (${(data.size / 1024 / 1024).toFixed(2)} MB)`);
272269
});
273270

@@ -280,6 +277,65 @@ async function main() {
280277
}
281278
});
282279

280+
// Handle download completion
281+
webTorrentManager.on('download-complete', async (data) => {
282+
logger.info(`✅ Download complete: ${data.name} (${data.size} bytes)`);
283+
284+
try {
285+
// Calculate hash of downloaded content
286+
const contentHash = crypto.createHash('sha256').update(data.buffer).digest('hex');
287+
288+
// Find the display name from the magnet URI
289+
const displayNameMatch = data.magnetUri.match(/dn=([^&]+)/);
290+
const displayName = displayNameMatch ? decodeURIComponent(displayNameMatch[1]) : `file-${Date.now()}`;
291+
292+
// Save the file with the display name or content hash
293+
const fileName = displayName.endsWith('.dig') ? displayName : `${contentHash}.dig`;
294+
const filePath = path.join(CONFIG.digDirectory, fileName);
295+
296+
// Check if we already have this file
297+
if (fs.existsSync(filePath)) {
298+
logger.info(`⏭️ File already exists: ${fileName}`);
299+
} else {
300+
fs.writeFileSync(filePath, data.buffer);
301+
logger.info(`💾 Saved file: ${fileName}`);
302+
303+
// Optionally seed the downloaded file
304+
try {
305+
await natTools.seedFile(filePath);
306+
logger.info(`🌱 Now seeding downloaded file: ${fileName}`);
307+
} catch (error) {
308+
logger.warn(`⚠️ Could not seed downloaded file:`, error.message);
309+
}
310+
}
311+
} catch (error) {
312+
logger.error(`❌ Error processing downloaded file:`, error.message);
313+
} finally {
314+
// Remove from downloading set
315+
downloadingFiles.delete(data.magnetUri);
316+
if (currentDownload === data.magnetUri) {
317+
currentDownload = null;
318+
}
319+
320+
// Process next download in queue
321+
setImmediate(() => processNextDownload(natTools));
322+
}
323+
});
324+
325+
// Handle download errors
326+
webTorrentManager.on('download-error', (data) => {
327+
logger.error(`❌ Download failed: ${data.magnetUri.substring(0, 50)}...`, data.error);
328+
329+
// Remove from downloading set
330+
downloadingFiles.delete(data.magnetUri);
331+
if (currentDownload === data.magnetUri) {
332+
currentDownload = null;
333+
}
334+
335+
// Process next download in queue
336+
setImmediate(() => processNextDownload(natTools));
337+
});
338+
283339
// Check availability
284340
const webTorrentAvailable = natTools.isWebTorrentAvailable();
285341
const registryAvailable = natTools.isRegistryAvailable();

src/nat-tools.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,23 +141,30 @@ export class NatTools {
141141
}
142142

143143
/**
144-
* Download a file from a magnet URI
144+
* Download a file from a magnet URI (fire-and-forget, listen to events from webTorrentManager)
145145
* @param magnetUri The magnet URI to download
146146
* @param maxFileSizeBytes Optional maximum file size limit
147-
* @returns Buffer containing the downloaded file
147+
*
148+
* Events emitted by webTorrentManager:
149+
* - 'download-metadata': When metadata is received
150+
* - 'download-progress': During download
151+
* - 'download-complete': When download finishes successfully
152+
* - 'download-error': If download fails
148153
*/
149-
public async downloadFromMagnet(magnetUri: string, maxFileSizeBytes?: number): Promise<Buffer> {
154+
public downloadFromMagnet(magnetUri: string, maxFileSizeBytes?: number): void {
150155
if (!this.isInitialized) {
151156
throw new Error("NatTools not initialized. Call initialize() first.");
152157
}
153158

154-
this.logger.info(`📥 Downloading from magnet URI...`);
159+
this.logger.info(`📥 Starting download from magnet URI...`);
155160

156-
const buffer = await webTorrentManager.downloadFile(magnetUri, maxFileSizeBytes);
157-
158-
this.logger.info(`✅ Download completed: ${buffer.length} bytes`);
159-
160-
return buffer;
161+
// Fire-and-forget: just start the download
162+
// Consumers should listen to webTorrentManager events:
163+
// - 'download-complete'
164+
// - 'download-error'
165+
// - 'download' (progress)
166+
// - 'metadata'
167+
webTorrentManager.downloadFile(magnetUri, maxFileSizeBytes);
161168
}
162169

163170
/**

0 commit comments

Comments
 (0)