feat: set uploading task concurrent limit

This commit is contained in:
HFO4 2022-04-13 18:32:49 +08:00
parent da7a3a38bf
commit 70aeb7a483
6 changed files with 121 additions and 25 deletions

View File

@ -0,0 +1,62 @@
import React, { useState } from "react";
import { Input, InputLabel, makeStyles } from "@material-ui/core";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from "@material-ui/core";
import FormControl from "@material-ui/core/FormControl";
import Auth from "../../middleware/Auth";
const useStyles = makeStyles((theme) => ({}));
export default function ConcurrentOptionDialog({ open, onClose, onSave }) {
const [count, setCount] = useState(
Auth.GetPreferenceWithDefault("concurrent_limit", "5")
);
const classes = useStyles();
return (
<Dialog
fullWidth
maxWidth={"xs"}
open={open}
onClose={onClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">任务并行数量</DialogTitle>
<DialogContent>
<FormControl fullWidth>
<InputLabel htmlFor="component-helper">
同时上传的任务数量
</InputLabel>
<Input
type={"number"}
inputProps={{
min: 1,
step: 1,
max: 20,
}}
value={count}
onChange={(e) => setCount(e.target.value)}
/>
</FormControl>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>取消</Button>
<div className={classes.wrapper}>
<Button
color="primary"
disabled={count === ""}
onClick={() => onSave(count)}
>
确定
</Button>
</div>
</DialogActions>
</Dialog>
);
}

View File

@ -6,7 +6,7 @@ import {
MenuItem,
Tooltip,
} from "@material-ui/core";
import React, { useCallback, useMemo } from "react";
import React, { useCallback, useMemo, useState } from "react";
import { useDispatch } from "react-redux";
import API from "../../../middleware/Api";
import { TaskType } from "../core/types";
@ -15,6 +15,9 @@ import Divider from "@material-ui/core/Divider";
import CheckIcon from "@material-ui/icons/Check";
import { DeleteEmpty } from "mdi-material-ui";
import DeleteIcon from "@material-ui/icons/Delete";
import ConcurrentOptionDialog from "../../Modals/ConcurrentOption";
import Auth from "../../../middleware/Auth";
import { ClearAll } from "@material-ui/icons";
const useStyles = makeStyles((theme) => ({
icon: {
@ -37,6 +40,7 @@ export default function MoreActions({
}) {
const classes = useStyles();
const dispatch = useDispatch();
const [concurrentDialog, setConcurrentDialog] = useState(false);
const ToggleSnackbar = useCallback(
(vertical, horizontal, msg, color) =>
dispatch(toggleSnackbar(vertical, horizontal, msg, color)),
@ -126,6 +130,13 @@ export default function MoreActions({
onClick: () => cleanFinished(),
icon: <DeleteIcon />,
text: "清除已完成任务",
divider: true,
},
{
tooltip: "清除列表中已完成、失败、被取消的任务",
onClick: () => setConcurrentDialog(true),
icon: <ClearAll />,
text: "设置并行数量",
divider: false,
},
],
@ -140,25 +151,44 @@ export default function MoreActions({
]
);
const onConcurrentLimitSave = (val) => {
val = parseInt(val);
if (val > 0) {
Auth.SetPreference("concurrent_limit", val);
uploadManager.changeConcurrentLimit(parseInt(val));
}
setConcurrentDialog(false);
};
return (
<Menu id={id} open={open} anchorEl={anchorEl} onClose={onClose}>
{listItems.map((item) => (
<>
<Tooltip
enterNextDelay={500}
key={item.text}
title={item.tooltip}
>
<MenuItem dense onClick={actionClicked(item.onClick)}>
<ListItemIcon className={classes.icon}>
{item.icon}
</ListItemIcon>
{item.text}
</MenuItem>
</Tooltip>
{item.divider && <Divider />}
</>
))}
</Menu>
<>
<Menu id={id} open={open} anchorEl={anchorEl} onClose={onClose}>
{listItems.map((item) => (
<>
<Tooltip
enterNextDelay={500}
key={item.text}
title={item.tooltip}
>
<MenuItem
dense
onClick={actionClicked(item.onClick)}
>
<ListItemIcon className={classes.icon}>
{item.icon}
</ListItemIcon>
{item.text}
</MenuItem>
</Tooltip>
{item.divider && <Divider />}
</>
))}
</Menu>
<ConcurrentOptionDialog
open={concurrentDialog}
onClose={() => setConcurrentDialog(false)}
onSave={onConcurrentLimitSave}
/>
</>
);
}

View File

@ -109,9 +109,6 @@ const filters = {
ongoing: (u) => u.status < Status.finished,
};
const getTaskListPreference = (key, defaultVal) =>
Auth.GetPreference(key) ? Auth.GetPreference(key) : defaultVal;
export default function TaskList({
open,
onClose,

View File

@ -13,6 +13,7 @@ import {
refreshStorage,
toggleSnackbar,
} from "../../redux/explorer";
import Auth from "../../middleware/Auth";
let totalProgressCollector = null;
let lastProgressStart = -1;
@ -82,7 +83,9 @@ export default function Uploader() {
const uploadManager = useMemo(() => {
return new UploadManager({
logLevel: "INFO",
concurrentLimit: 5,
concurrentLimit: parseInt(
Auth.GetPreferenceWithDefault("concurrent_limit", "5")
),
dropZone: document.querySelector("body"),
onToast: (type, msg) => {
ToggleSnackbar("top", "right", msg, type);

View File

@ -79,6 +79,10 @@ export default class UploadManager {
}
}
changeConcurrentLimit = (newLimit: number) => {
this.pool.limit = newLimit;
};
dispatchUploader(task: Task): Base {
if (task.type == TaskType.resumeHint) {
return new ResumeHint(task, this);

View File

@ -11,7 +11,7 @@ export class Pool {
queue: Array<QueueContent> = [];
processing: Array<QueueContent> = [];
constructor(private limit: number) {}
constructor(public limit: number) {}
enqueue(uploader: Base) {
return new Promise<void>((resolve, reject) => {