diff --git a/ui/src/actions/tasksActions.ts b/ui/src/actions/tasksActions.ts index 5af58d0..ea9b50e 100644 --- a/ui/src/actions/tasksActions.ts +++ b/ui/src/actions/tasksActions.ts @@ -133,11 +133,14 @@ export type TasksActionTypes = | ListDeadTasksSuccessAction | ListDeadTasksErrorAction; -export function listActiveTasksAsync(qname: string) { +export function listActiveTasksAsync( + qname: string, + pageOpts?: PaginationOptions +) { return async (dispatch: Dispatch) => { dispatch({ type: LIST_ACTIVE_TASKS_BEGIN, queue: qname }); try { - const response = await listActiveTasks(qname); + const response = await listActiveTasks(qname, pageOpts); dispatch({ type: LIST_ACTIVE_TASKS_SUCCESS, queue: qname, diff --git a/ui/src/components/ActiveTasksTable.tsx b/ui/src/components/ActiveTasksTable.tsx index 8edb9e4..a763cc5 100644 --- a/ui/src/components/ActiveTasksTable.tsx +++ b/ui/src/components/ActiveTasksTable.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useState, useCallback } from "react"; import { connect, ConnectedProps } from "react-redux"; import { makeStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; @@ -28,6 +28,7 @@ import TablePaginationActions, { rowsPerPageOptions, defaultPageSize, } from "./TablePaginationActions"; +import { usePolling } from "../hooks"; const useStyles = makeStyles({ table: { @@ -73,14 +74,12 @@ function ActiveTasksTable(props: Props & ReduxProps) { setPage(0); }; - useEffect(() => { - listActiveTasksAsync(queue); - const interval = setInterval( - () => listActiveTasksAsync(queue), - pollInterval * 1000 - ); - return () => clearInterval(interval); - }, [pollInterval, listActiveTasksAsync, queue]); + const fetchData = useCallback(() => { + const pageOpts = { page: page + 1, size: pageSize }; + listActiveTasksAsync(queue, pageOpts); + }, [page, pageSize, queue, listActiveTasksAsync]); + + usePolling(fetchData, pollInterval); if (props.tasks.length === 0) { return ( diff --git a/ui/src/components/DeadTasksTable.tsx b/ui/src/components/DeadTasksTable.tsx index c6531b8..a8ed6ac 100644 --- a/ui/src/components/DeadTasksTable.tsx +++ b/ui/src/components/DeadTasksTable.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useCallback, useState } from "react"; import { connect, ConnectedProps } from "react-redux"; import { makeStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; @@ -29,6 +29,7 @@ import TablePaginationActions, { rowsPerPageOptions, } from "./TablePaginationActions"; import { timeAgo } from "../timeutil"; +import { usePolling } from "../hooks"; const useStyles = makeStyles({ table: { @@ -83,14 +84,12 @@ function DeadTasksTable(props: Props & ReduxProps) { setPage(0); }; - useEffect(() => { + const fetchData = useCallback(() => { const pageOpts = { page: page + 1, size: pageSize }; listDeadTasksAsync(queue, pageOpts); - const interval = setInterval(() => { - listDeadTasksAsync(queue, pageOpts); - }, pollInterval * 1000); - return () => clearInterval(interval); - }, [pollInterval, listDeadTasksAsync, queue, page, pageSize]); + }, [page, pageSize, queue, listDeadTasksAsync]); + + usePolling(fetchData, pollInterval); if (props.tasks.length === 0) { return ( diff --git a/ui/src/components/PendingTasksTable.tsx b/ui/src/components/PendingTasksTable.tsx index 97047fd..e121365 100644 --- a/ui/src/components/PendingTasksTable.tsx +++ b/ui/src/components/PendingTasksTable.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useCallback, useState } from "react"; import { connect, ConnectedProps } from "react-redux"; import { makeStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; @@ -28,6 +28,7 @@ import TablePaginationActions, { import { listPendingTasksAsync } from "../actions/tasksActions"; import { AppState } from "../store"; import { PendingTask } from "../api"; +import { usePolling } from "../hooks"; const useStyles = makeStyles({ table: { @@ -74,14 +75,12 @@ function PendingTasksTable(props: Props & ReduxProps) { setPage(0); }; - useEffect(() => { + const fetchData = useCallback(() => { const pageOpts = { page: page + 1, size: pageSize }; listPendingTasksAsync(queue, pageOpts); - const interval = setInterval(() => { - listPendingTasksAsync(queue, pageOpts); - }, pollInterval * 1000); - return () => clearInterval(interval); - }, [pollInterval, listPendingTasksAsync, queue, page, pageSize]); + }, [page, pageSize, queue, listPendingTasksAsync]); + + usePolling(fetchData, pollInterval); if (props.tasks.length === 0) { return ( diff --git a/ui/src/components/ProcessedTasksChart.tsx b/ui/src/components/ProcessedTasksChart.tsx index f0b1aa2..9031e07 100644 --- a/ui/src/components/ProcessedTasksChart.tsx +++ b/ui/src/components/ProcessedTasksChart.tsx @@ -25,7 +25,7 @@ function ProcessedTasksChart(props: Props) { const theme = useTheme(); return ( - + diff --git a/ui/src/components/QueueSizeChart.tsx b/ui/src/components/QueueSizeChart.tsx index abc91b0..2f1a0b2 100644 --- a/ui/src/components/QueueSizeChart.tsx +++ b/ui/src/components/QueueSizeChart.tsx @@ -26,7 +26,7 @@ interface TaskBreakdown { function QueueSizeChart(props: Props) { return ( - + diff --git a/ui/src/components/RetryTasksTable.tsx b/ui/src/components/RetryTasksTable.tsx index 6f3ff74..f59f562 100644 --- a/ui/src/components/RetryTasksTable.tsx +++ b/ui/src/components/RetryTasksTable.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useCallback, useState } from "react"; import { connect, ConnectedProps } from "react-redux"; import { makeStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; @@ -29,6 +29,7 @@ import TablePaginationActions, { rowsPerPageOptions, } from "./TablePaginationActions"; import { durationBefore } from "../timeutil"; +import { usePolling } from "../hooks"; const useStyles = makeStyles({ table: { @@ -75,14 +76,12 @@ function RetryTasksTable(props: Props & ReduxProps) { setPage(0); }; - useEffect(() => { + const fetchData = useCallback(() => { const pageOpts = { page: page + 1, size: pageSize }; listRetryTasksAsync(queue, pageOpts); - const interval = setInterval(() => { - listRetryTasksAsync(queue, pageOpts); - }, pollInterval * 1000); - return () => clearInterval(interval); - }, [pollInterval, listRetryTasksAsync, queue, page, pageSize]); + }, [page, pageSize, queue, listRetryTasksAsync]); + + usePolling(fetchData, pollInterval); if (props.tasks.length === 0) { return ( diff --git a/ui/src/components/ScheduledTasksTable.tsx b/ui/src/components/ScheduledTasksTable.tsx index 4c758be..2527355 100644 --- a/ui/src/components/ScheduledTasksTable.tsx +++ b/ui/src/components/ScheduledTasksTable.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useState, useCallback } from "react"; import { connect, ConnectedProps } from "react-redux"; import { makeStyles } from "@material-ui/core/styles"; import Table from "@material-ui/core/Table"; @@ -29,6 +29,7 @@ import TablePaginationActions, { rowsPerPageOptions, } from "./TablePaginationActions"; import { durationBefore } from "../timeutil"; +import { usePolling } from "../hooks"; const useStyles = makeStyles({ table: { @@ -75,14 +76,12 @@ function ScheduledTasksTable(props: Props & ReduxProps) { setPage(0); }; - useEffect(() => { + const fetchData = useCallback(() => { const pageOpts = { page: page + 1, size: pageSize }; listScheduledTasksAsync(queue, pageOpts); - const interval = setInterval(() => { - listScheduledTasksAsync(queue, pageOpts); - }, pollInterval * 1000); - return () => clearInterval(interval); - }, [pollInterval, listScheduledTasksAsync, queue, page, pageSize]); + }, [page, pageSize, queue, listScheduledTasksAsync]); + + usePolling(fetchData, pollInterval); if (props.tasks.length === 0) { return ( diff --git a/ui/src/hooks/index.tsx b/ui/src/hooks/index.tsx new file mode 100644 index 0000000..cd6184f --- /dev/null +++ b/ui/src/hooks/index.tsx @@ -0,0 +1,11 @@ +import { useEffect } from "react"; + +// usePolling repeatedly calls doFn with a fix time delay specified +// by interval (in millisecond). +export function usePolling(doFn: () => void, interval: number) { + useEffect(() => { + doFn(); + const id = setInterval(doFn, interval * 1000); + return () => clearInterval(id); + }, [interval, doFn]); +} diff --git a/ui/src/views/DashboardView.tsx b/ui/src/views/DashboardView.tsx index 66eced1..4316584 100644 --- a/ui/src/views/DashboardView.tsx +++ b/ui/src/views/DashboardView.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React from "react"; import { connect, ConnectedProps } from "react-redux"; import Container from "@material-ui/core/Container"; import { makeStyles } from "@material-ui/core/styles"; @@ -18,6 +18,7 @@ import ProcessedTasksChart from "../components/ProcessedTasksChart"; import QueuesOverviewTable from "../components/QueuesOverviewTable"; import Tooltip from "../components/Tooltip"; import { getCurrentUTCDate } from "../timeutil"; +import { usePolling } from "../hooks"; const useStyles = makeStyles((theme) => ({ container: { @@ -78,11 +79,7 @@ function DashboardView(props: Props) { const { pollInterval, listQueuesAsync, queues } = props; const classes = useStyles(); - useEffect(() => { - listQueuesAsync(); - const interval = setInterval(listQueuesAsync, pollInterval * 1000); - return () => clearInterval(interval); - }, [pollInterval, listQueuesAsync]); + usePolling(listQueuesAsync, pollInterval); const processedStats = queues.map((q) => ({ queue: q.queue,