Seems alright now

This commit is contained in:
Igor Katson 2023-11-25 00:54:21 +00:00
parent 17b243921d
commit fa97dedb98
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
5 changed files with 50 additions and 31 deletions

View file

@ -87,6 +87,16 @@ impl ChunkTracker {
self.needed_pieces.set(index.get() as usize, false)
}
pub fn calc_have_bytes(&self) -> u64 {
self.have
.iter_ones()
.filter_map(|piece_id| {
let piece_id = self.lengths.validate_piece_index(piece_id as u32)?;
Some(self.lengths.piece_length(piece_id) as u64)
})
.sum()
}
pub fn iter_needed_pieces(&self) -> impl Iterator<Item = usize> + '_ {
self.priority_piece_ids
.iter()

View file

@ -167,9 +167,7 @@ pub struct TorrentStateLive {
files: Vec<Arc<Mutex<File>>>,
filenames: Vec<PathBuf>,
// TODO: why the hell do we need these here, remove it.
needed_bytes: u64,
have_plus_needed_bytes: u64,
initially_needed_bytes: u64,
stats: AtomicStats,
lengths: Lengths,
@ -213,8 +211,7 @@ impl TorrentStateLive {
have_bytes: AtomicU64::new(have_bytes),
..Default::default()
},
needed_bytes,
have_plus_needed_bytes: needed_bytes + have_bytes,
initially_needed_bytes: needed_bytes,
lengths,
peer_semaphore: Semaphore::new(128),
peer_queue_tx,
@ -454,7 +451,7 @@ impl TorrentStateLive {
FileOps::new(&self.meta.info, &self.files, &self.lengths)
}
pub fn initially_needed(&self) -> u64 {
self.needed_bytes
self.initially_needed_bytes
}
pub(crate) fn lock_read(
@ -518,7 +515,7 @@ impl TorrentStateLive {
.load(Ordering::Acquire)
}
pub fn get_have_bytes(&self) -> u64 {
pub fn get_approx_have_bytes(&self) -> u64 {
self.stats.have_bytes.load(Ordering::Relaxed)
}
@ -527,7 +524,7 @@ impl TorrentStateLive {
}
pub fn get_left_to_download_bytes(&self) -> u64 {
self.needed_bytes - self.get_downloaded_bytes()
self.initially_needed_bytes - self.get_downloaded_bytes()
}
fn maybe_transmit_haves(&self, index: ValidPieceIndex) {
@ -601,15 +598,15 @@ impl TorrentStateLive {
pub fn stats_snapshot(&self) -> StatsSnapshot {
use Ordering::*;
let downloaded_bytes = self.stats.downloaded_and_checked_bytes.load(Relaxed);
let remaining = self.needed_bytes - downloaded_bytes;
let remaining = self.initially_needed_bytes - downloaded_bytes;
StatsSnapshot {
have_bytes: self.stats.have_bytes.load(Relaxed),
downloaded_and_checked_bytes: downloaded_bytes,
downloaded_and_checked_pieces: self.stats.downloaded_and_checked_pieces.load(Relaxed),
fetched_bytes: self.stats.fetched_bytes.load(Relaxed),
uploaded_bytes: self.stats.uploaded_bytes.load(Relaxed),
total_bytes: self.have_plus_needed_bytes,
initially_needed_bytes: self.needed_bytes,
total_bytes: self.lengths.total_length(),
initially_needed_bytes: self.initially_needed_bytes,
remaining_bytes: remaining,
total_piece_download_ms: self.stats.total_piece_download_ms.load(Relaxed),
peer_stats: self.peers.stats(),
@ -653,16 +650,22 @@ impl TorrentStateLive {
let filenames = self.filenames.clone();
let mut chunk_tracker = g
.chunks
.take()
.context("bug: pausing already paused torrent")?;
for piece_id in g.inflight_pieces.keys().copied() {
chunk_tracker.mark_piece_broken(piece_id);
}
let have_bytes = chunk_tracker.calc_have_bytes();
// g.chunks;
Ok(TorrentStatePaused {
info: self.meta.clone(),
files,
filenames,
chunk_tracker: g
.chunks
.take()
.context("bug: pausing already paused torrent")?,
have_bytes: self.get_have_bytes(),
chunk_tracker,
have_bytes,
})
}
}
@ -765,7 +768,7 @@ impl<'a> PeerConnectionHandler for &'a PeerHandler {
}
fn get_have_bytes(&self) -> u64 {
self.state.get_have_bytes()
self.state.get_approx_have_bytes()
}
}

File diff suppressed because one or more lines are too long

View file

@ -8,6 +8,8 @@
<!-- Include Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css"
integrity="sha384-4LISF5TTJX/fLmGSxO53rV4miRxdg84mZsxmO8Rx5jGtp/LbrixFETvWa5a6sESd" crossorigin="anonymous">
<script type="module" crossorigin src="app.js"></script>
</head>

View file

@ -1,7 +1,7 @@
import { MouseEventHandler, StrictMode, createContext, useContext, useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom/client';
import { ProgressBar, Button, Container, Row, Col, Alert, Modal, Form, Spinner, Table } from 'react-bootstrap';
import { AddTorrentResponse, TorrentDetails, TorrentFile, TorrentId, TorrentStats, ErrorDetails, API, STATE_INITIALIZING, STATE_LIVE } from './api';
import { AddTorrentResponse, TorrentDetails, TorrentFile, TorrentId, TorrentStats, ErrorDetails, API, STATE_INITIALIZING, STATE_LIVE, STATE_PAUSED } from './api';
interface Error {
text: string,
@ -161,7 +161,7 @@ const TorrentRow: React.FC<{
const progressPercentage = error ? 100 : (progressBytes / totalBytes) * 100;
const isAnimated = (state == STATE_INITIALIZING || state == STATE_LIVE) && !finished;
const progressLabel = error ? 'Error' : `${progressPercentage.toFixed(2)}%`;
const progressBarVariant = error ? 'danger' : finished ? 'success' : 'info';
const progressBarVariant = error ? 'danger' : finished ? 'success' : 'primary';
const formatPeersString = () => {
let peer_stats = statsResponse?.live?.snapshot.peer_stats;
@ -206,8 +206,12 @@ const TorrentRow: React.FC<{
{statsResponse ?
<>
<Column label="Size">{`${formatBytes(totalBytes)} `}</Column>
<Column size={2} label="Progress">
<ProgressBar now={progressPercentage} label={progressLabel} animated={isAnimated} variant={progressBarVariant} />
<Column size={2} label={state == STATE_PAUSED ? 'Progress (PAUSED)' : 'Progress'}>
<ProgressBar
now={progressPercentage}
label={progressLabel}
animated={isAnimated}
variant={progressBarVariant} />
</Column>
<Column size={2} label="Down Speed">{formatDownloadSped()}</Column>
<Column label="ETA">{getCompletionETA(statsResponse)}</Column>