diff --git a/awx/ui_next/src/components/JobList/useWsJobs.js b/awx/ui_next/src/components/JobList/useWsJobs.js index 9c939f25d9..4560930818 100644 --- a/awx/ui_next/src/components/JobList/useWsJobs.js +++ b/awx/ui_next/src/components/JobList/useWsJobs.js @@ -1,5 +1,6 @@ -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; +import useWebsocket from '../../util/useWebsocket'; import useThrottle from '../../util/useThrottle'; import { parseQueryString } from '../../util/qs'; import sortJobs from './sortJobs'; @@ -7,9 +8,13 @@ import sortJobs from './sortJobs'; export default function useWsJobs(initialJobs, fetchJobsById, qsConfig) { const location = useLocation(); const [jobs, setJobs] = useState(initialJobs); - const [lastMessage, setLastMessage] = useState(null); const [jobsToFetch, setJobsToFetch] = useState([]); const throttledJobsToFetch = useThrottle(jobsToFetch, 5000); + const lastMessage = useWebsocket({ + jobs: ['status_changed'], + schedules: ['changed'], + control: ['limit_reached_1'], + }); useEffect(() => { setJobs(initialJobs); @@ -37,8 +42,6 @@ export default function useWsJobs(initialJobs, fetchJobsById, qsConfig) { })(); }, [throttledJobsToFetch, fetchJobsById]); // eslint-disable-line react-hooks/exhaustive-deps - const ws = useRef(null); - useEffect(() => { if (!lastMessage || !lastMessage.unified_job_id) { return; @@ -61,51 +64,6 @@ export default function useWsJobs(initialJobs, fetchJobsById, qsConfig) { } }, [lastMessage]); // eslint-disable-line react-hooks/exhaustive-deps - useEffect(() => { - ws.current = new WebSocket(`wss://${window.location.host}/websocket/`); - - const connect = () => { - const xrftoken = `; ${document.cookie}` - .split('; csrftoken=') - .pop() - .split(';') - .shift(); - ws.current.send( - JSON.stringify({ - xrftoken, - groups: { - jobs: ['status_changed'], - schedules: ['changed'], - control: ['limit_reached_1'], - }, - }) - ); - }; - ws.current.onopen = connect; - - ws.current.onmessage = e => { - setLastMessage(JSON.parse(e.data)); - }; - - ws.current.onclose = e => { - // eslint-disable-next-line no-console - console.debug('Socket closed. Reconnecting...', e); - setTimeout(() => { - connect(); - }, 1000); - }; - - ws.current.onerror = err => { - // eslint-disable-next-line no-console - console.debug('Socket error: ', err, 'Disconnecting...'); - ws.current.close(); - }; - - return () => { - ws.current.close(); - }; - }, []); - return jobs; } diff --git a/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js b/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js index d9886c29c4..13871490f3 100644 --- a/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js +++ b/awx/ui_next/src/screens/Inventory/InventoryList/useWsInventories.js @@ -1,4 +1,5 @@ -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect } from 'react'; +import useWebsocket from '../../../util/useWebsocket'; import useThrottle from '../../../util/useThrottle'; export default function useWsProjects( @@ -6,10 +7,13 @@ export default function useWsProjects( fetchInventoriesById ) { const [inventories, setInventories] = useState(initialInventories); - const [lastMessage, setLastMessage] = useState(null); const [inventoriesToFetch, setInventoriesToFetch] = useState([]); const throttledInventoriesToFetch = useThrottle(inventoriesToFetch, 5000); - const ws = useRef(null); + const lastMessage = useWebsocket({ + inventories: ['status_changed'], + jobs: ['status_changed'], + control: ['limit_reached_1'], + }); useEffect(() => { setInventories(initialInventories); @@ -84,50 +88,5 @@ export default function useWsProjects( [lastMessage] ); - useEffect(() => { - ws.current = new WebSocket(`wss://${window.location.host}/websocket/`); - - const connect = () => { - const xrftoken = `; ${document.cookie}` - .split('; csrftoken=') - .pop() - .split(';') - .shift(); - ws.current.send( - JSON.stringify({ - xrftoken, - groups: { - inventories: ['status_changed'], - jobs: ['status_changed'], - control: ['limit_reached_1'], - }, - }) - ); - }; - ws.current.onopen = connect; - - ws.current.onmessage = e => { - setLastMessage(JSON.parse(e.data)); - }; - - ws.current.onclose = e => { - // eslint-disable-next-line no-console - console.debug('Socket closed. Reconnecting...', e); - setTimeout(() => { - connect(); - }, 1000); - }; - - ws.current.onerror = err => { - // eslint-disable-next-line no-console - console.debug('Socket error: ', err, 'Disconnecting...'); - ws.current.close(); - }; - - return () => { - ws.current.close(); - }; - }, []); - return inventories; } diff --git a/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js b/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js index a5c46319ba..38303c9ed3 100644 --- a/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js +++ b/awx/ui_next/src/screens/Project/ProjectList/useWsProjects.js @@ -1,9 +1,12 @@ -import { useState, useEffect, useRef } from 'react'; +import { useState, useEffect } from 'react'; +import useWebsocket from '../../../util/useWebsocket'; export default function useWsProjects(initialProjects) { const [projects, setProjects] = useState(initialProjects); - const [lastMessage, setLastMessage] = useState(null); - const ws = useRef(null); + const lastMessage = useWebsocket({ + jobs: ['status_changed'], + control: ['limit_reached_1'], + }); useEffect(() => { setProjects(initialProjects); @@ -37,49 +40,5 @@ export default function useWsProjects(initialProjects) { ]); }, [lastMessage]); // eslint-disable-line react-hooks/exhaustive-deps - useEffect(() => { - ws.current = new WebSocket(`wss://${window.location.host}/websocket/`); - - const connect = () => { - const xrftoken = `; ${document.cookie}` - .split('; csrftoken=') - .pop() - .split(';') - .shift(); - ws.current.send( - JSON.stringify({ - xrftoken, - groups: { - jobs: ['status_changed'], - control: ['limit_reached_1'], - }, - }) - ); - }; - ws.current.onopen = connect; - - ws.current.onmessage = e => { - setLastMessage(JSON.parse(e.data)); - }; - - ws.current.onclose = e => { - // eslint-disable-next-line no-console - console.debug('Socket closed. Reconnecting...', e); - setTimeout(() => { - connect(); - }, 1000); - }; - - ws.current.onerror = err => { - // eslint-disable-next-line no-console - console.debug('Socket error: ', err, 'Disconnecting...'); - ws.current.close(); - }; - - return () => { - ws.current.close(); - }; - }, []); - return projects; } diff --git a/awx/ui_next/src/util/useWebsocket.js b/awx/ui_next/src/util/useWebsocket.js new file mode 100644 index 0000000000..c04d086f35 --- /dev/null +++ b/awx/ui_next/src/util/useWebsocket.js @@ -0,0 +1,49 @@ +import { useState, useEffect, useRef } from 'react'; + +export default function useWebsocket(subscribeGroups) { + const [lastMessage, setLastMessage] = useState(null); + const ws = useRef(null); + + useEffect(function setupSocket() { + ws.current = new WebSocket(`wss://${window.location.host}/websocket/`); + + const connect = () => { + const xrftoken = `; ${document.cookie}` + .split('; csrftoken=') + .pop() + .split(';') + .shift(); + ws.current.send( + JSON.stringify({ + xrftoken, + groups: subscribeGroups, + }) + ); + }; + ws.current.onopen = connect; + + ws.current.onmessage = e => { + setLastMessage(JSON.parse(e.data)); + }; + + ws.current.onclose = e => { + // eslint-disable-next-line no-console + console.debug('Socket closed. Reconnecting...', e); + setTimeout(() => { + connect(); + }, 1000); + }; + + ws.current.onerror = err => { + // eslint-disable-next-line no-console + console.debug('Socket error: ', err, 'Disconnecting...'); + ws.current.close(); + }; + + return () => { + ws.current.close(); + }; + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + return lastMessage; +}