Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/javi11/nntppool/v4 v4.10.0
github.com/javi11/nxg v0.1.0
github.com/javi11/nzbparser v0.5.4
github.com/javi11/rardecode/v2 v2.1.2-0.20260402111111-85298dd02bf6
github.com/javi11/rardecode/v2 v2.1.2-0.20260424080037-11b2fa852f05
github.com/javi11/sevenzip v1.6.2-0.20251026160715-ca961b7f1239
github.com/jinzhu/copier v0.4.0
github.com/klauspost/compress v1.18.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ github.com/javi11/nzbparser v0.5.4 h1:0aYyORZipp7iX8eNpT/efnzCeVO+9C0sE2HWCGc/Ja
github.com/javi11/nzbparser v0.5.4/go.mod h1:ikF7WI3BUGs5IHQJmKzmtTkX29NZW5nvUdo6ZWFZgL4=
github.com/javi11/rardecode/v2 v2.1.2-0.20260402111111-85298dd02bf6 h1:V/OLStIqC6nAlfL+iD5VvcrjTFkkhyfDAbWxp5zpMys=
github.com/javi11/rardecode/v2 v2.1.2-0.20260402111111-85298dd02bf6/go.mod h1:Bv+b+FzxIO1GhbQB6Rl+um+6nGsfcB+1eug62+8P9OM=
github.com/javi11/rardecode/v2 v2.1.2-0.20260424080037-11b2fa852f05 h1:zTxsTHCgYTqG7AQzE0ngczTeWSneDOLyEWDrPVMzcnU=
github.com/javi11/rardecode/v2 v2.1.2-0.20260424080037-11b2fa852f05/go.mod h1:Bv+b+FzxIO1GhbQB6Rl+um+6nGsfcB+1eug62+8P9OM=
github.com/javi11/sevenzip v1.6.2-0.20251026160715-ca961b7f1239 h1:XbptA/1kHKOeDZChh599BXNGQ9jfuW1RG8y/e5Oclkc=
github.com/javi11/sevenzip v1.6.2-0.20251026160715-ca961b7f1239/go.mod h1:+nqMTvWJKqRUQRE0uWjip5scep1PoEk+ZPDX2YwWSSo=
github.com/jgautheron/goconst v1.8.2 h1:y0XF7X8CikZ93fSNT6WBTb/NElBu9IjaY7CCYQrCMX4=
Expand Down
23 changes: 20 additions & 3 deletions internal/importer/parser/par2/descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ func readFileDescriptors(
return descriptors, fmt.Errorf("PAR2 file has no segments")
}

// Create context with timeout (30 seconds per segment should be enough)
// For multi-segment files, this gives adequate time
ctx, cancel := context.WithTimeout(ctx, time.Second*30*time.Duration(len(par2File.Segments)))
// Create context with timeout (30s per segment, capped at 90s ceiling).
// Capping prevents runaway waits on large index files where the real cost
// is dominated by latency, not sequential segment fetches.
timeout := min(time.Second*30*time.Duration(len(par2File.Segments)), 90*time.Second)
ctx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()

// Build segment loader and compute total size
Expand All @@ -132,6 +134,11 @@ func readFileDescriptors(
// Increase limit to accommodate larger PAR2 files with many FileDesc packets
maxPackets := 1000 // Limit the number of packets to process
packetCount := 0
// Once FileDesc packets stop appearing, PAR2 index files typically have no
// more ahead. Break after a window of non-FileDesc packets past the last
// descriptor to avoid draining the entire index unnecessarily.
const noNewDescWindow = 50
packetsSinceLastDesc := 0
var lastError error

for packetCount < maxPackets {
Expand Down Expand Up @@ -168,6 +175,7 @@ func readFileDescriptors(
}

descriptors = append(descriptors, *desc)
packetsSinceLastDesc = 0
} else {
// Skip non-FileDesc packets
if err := packetReader.SkipPacketBody(header); err != nil {
Expand All @@ -177,6 +185,15 @@ func readFileDescriptors(
slog.DebugContext(ctx, "Corrupted packet body encountered, returning partial PAR2 descriptors", "error", err, "descriptors_found", len(descriptors))
break
}
if len(descriptors) > 0 {
packetsSinceLastDesc++
if packetsSinceLastDesc >= noNewDescWindow {
slog.DebugContext(ctx, "No new FileDesc packets in window, ending PAR2 scan early",
"descriptors_found", len(descriptors),
"window", noNewDescWindow)
break
}
}
}
}

Expand Down
Loading
Loading