fix: collection of ui refresh timing bugs

This commit is contained in:
Gareth
2024-05-26 21:36:40 -07:00
parent 6ca90ecd8a
commit b218bc9409
3 changed files with 69 additions and 30 deletions
+5
View File
@@ -15,6 +15,7 @@ import {
export const ActivityBar = () => {
const [activeOperations, setActiveOperations] = useState<Operation[]>([]);
const setRefresh = useState<number>(0)[1];
useEffect(() => {
const callback = ({ operation, type }: OperationEvent) => {
@@ -32,6 +33,10 @@ export const ActivityBar = () => {
subscribeToOperations(callback);
setInterval(() => {
setRefresh((r) => r + 1);
}, 500);
return () => {
unsubscribeFromOperations(callback);
};
+11
View File
@@ -59,6 +59,17 @@ export const OperationRow = ({
const showModal = useShowModal();
const details = detailsForOperation(operation);
const displayType = getTypeForDisplay(operation);
const setRefresh = useState(0)[1];
useEffect(() => {
if (operation.status === OperationStatus.STATUS_INPROGRESS) {
const interval = setInterval(() => {
setRefresh((x) => x + 1);
}, 1000);
return () => clearInterval(interval);
}
}, [operation.status]);
let avatar: React.ReactNode;
switch (displayType) {
case DisplayType.BACKUP:
+53 -30
View File
@@ -13,13 +13,19 @@ import { formatBytes, formatDate } from "../lib/formatting";
import { Col, Empty, Row } from "antd";
import {
Operation,
OperationEvent,
OperationStats,
OperationStatus,
} from "../../gen/ts/v1/operations_pb";
import { useAlertApi } from "./Alerts";
import { BackupInfoCollector, getOperations } from "../state/oplog";
import {
BackupInfoCollector,
getOperations,
subscribeToOperations,
} from "../state/oplog";
import { MAX_OPERATION_HISTORY } from "../constants";
import { GetOperationsRequest, OpSelector } from "../../gen/ts/v1/service_pb";
import _ from "lodash";
const StatsPanel = ({ repoId }: { repoId: string }) => {
const [operations, setOperations] = useState<Operation[]>([]);
@@ -30,36 +36,53 @@ const StatsPanel = ({ repoId }: { repoId: string }) => {
return;
}
const backupCollector = new BackupInfoCollector((op) => {
return (
op.status === OperationStatus.STATUS_SUCCESS &&
op.op.case === "operationStats" &&
!!op.op.value.stats
);
});
getOperations(
new GetOperationsRequest({
selector: new OpSelector({
repoId: repoId,
}),
lastN: BigInt(MAX_OPERATION_HISTORY),
})
)
.then((ops) => {
backupCollector.bulkAddOperations(ops);
const operations = backupCollector
.getAll()
.flatMap((b) => b.operations);
operations.sort((a, b) => {
return Number(b.unixTimeEndMs - a.unixTimeEndMs);
});
setOperations(operations);
})
.catch((e) => {
alertApi!.error("Failed to fetch operations: " + e.message);
const refreshOperations = _.debounce(() => {
const backupCollector = new BackupInfoCollector((op) => {
return (
op.status === OperationStatus.STATUS_SUCCESS &&
op.op.case === "operationStats" &&
!!op.op.value.stats
);
});
getOperations(
new GetOperationsRequest({
selector: new OpSelector({
repoId: repoId,
}),
lastN: BigInt(MAX_OPERATION_HISTORY),
})
)
.then((ops) => {
backupCollector.bulkAddOperations(ops);
const operations = backupCollector
.getAll()
.flatMap((b) => b.operations);
operations.sort((a, b) => {
return Number(b.unixTimeEndMs - a.unixTimeEndMs);
});
setOperations(operations);
})
.catch((e) => {
alertApi!.error("Failed to fetch operations: " + e.message);
});
}, 1000);
refreshOperations();
const handler = (event: OperationEvent) => {
if (
event.operation?.repoId == repoId &&
event.operation?.op?.case === "operationStats"
) {
refreshOperations();
}
};
subscribeToOperations(handler);
return () => {}; // cleanup
}, [repoId]);
if (operations.length === 0) {