Skip to content
Open
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
106 changes: 105 additions & 1 deletion src/WrapperApp/components/Simulation/Geant4DatasetDownload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,95 @@ export enum Geant4DatasetsType {
FULL
}

function formatTime(seconds: number): string {
if (seconds < 1) {
return '<1s';
}

const totalSeconds = Math.ceil(seconds);

if (totalSeconds < 60) {
return `${totalSeconds}s`;
}

const minutes = Math.floor(totalSeconds / 60);
const remainingSeconds = totalSeconds % 60;

return `${minutes}m ${remainingSeconds}s`;
}

interface SpeedHistory {
lastDone: number;
lastTime: number;
currentSpeed: number;
}

const SMOOTHING = 0.1;

function DatasetCurrentStatus(props: { status: DatasetStatus }) {
const { status } = props;

const [speedHistory, setSpeedHistory] = useState<SpeedHistory>({
lastDone: status.done ?? 0,
lastTime: Date.now(),
currentSpeed: 0
});

useEffect(() => {
const currentDone = status.done ?? 0;
const currentTime = Date.now();

if (status.status === DatasetDownloadStatus.DOWNLOADING) {
setSpeedHistory(prev => {
const timeDelta = (currentTime - prev.lastTime) / 1000;
const bytesDelta = currentDone - prev.lastDone;

Comment thread
martastn marked this conversation as resolved.
if (bytesDelta > 0 && timeDelta > 0) {
const instSpeed = bytesDelta / timeDelta;

const newSpeed =
prev.currentSpeed === 0
? instSpeed
: prev.currentSpeed * (1 - SMOOTHING) + instSpeed * SMOOTHING;

return {
lastDone: currentDone,
lastTime: currentTime,
currentSpeed: newSpeed
};
}

return {
...prev,
lastTime: currentTime
};
});
}

if (
status.status === DatasetDownloadStatus.DONE ||
status.status === DatasetDownloadStatus.IDLE
) {
setSpeedHistory({
lastDone: status.done ?? 0,
lastTime: Date.now(),
currentSpeed: 0
});
}
}, [status.done, status.status]);

const remainingBytes = (status.total ?? 0) - (status.done ?? 0);
let estimatedTimeRemaining = '';

if (
status.status === DatasetDownloadStatus.DOWNLOADING &&
speedHistory.currentSpeed > 0 &&
remainingBytes > 0
) {
const remainingSeconds = remainingBytes / speedHistory.currentSpeed;
estimatedTimeRemaining = ` (est. ${formatTime(remainingSeconds)} remaining)`;
}

const idleIcon = status.cached ? (
<StorageIcon color='primary' />
) : (
Expand Down Expand Up @@ -68,13 +154,28 @@ function DatasetCurrentStatus(props: { status: DatasetStatus }) {
variant='indeterminate'
color='warning'
/>
],
[
DatasetDownloadStatus.IDLE,
<LinearProgress
color='info'
variant='indeterminate'
Comment thread
martastn marked this conversation as resolved.
Comment thread
martastn marked this conversation as resolved.
/>
]
]);

return (
<Box sx={{ pb: 1 }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<Typography sx={{ flex: 1 }}>{status.name}</Typography>

{status.status === DatasetDownloadStatus.DOWNLOADING && (
<Typography
fontSize={12}
color='text.secondary'>
{estimatedTimeRemaining}
</Typography>
)}
Comment thread
martastn marked this conversation as resolved.
Comment thread
martastn marked this conversation as resolved.
{datasetStatusIcon.get(status.status)}
</Box>

Expand Down Expand Up @@ -324,7 +425,10 @@ export function Geant4Datasets() {
}}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
onClick={() => setOpen(!open)}>
onClick={e => {
e.stopPropagation();
setOpen(!open);
Comment thread
martastn marked this conversation as resolved.
}}>
<Typography
textTransform='none'
fontSize={16}>
Expand Down
Loading