Make eventStream connection/reconnection more reliable

Also more logs on the server
This commit is contained in:
Deluan
2020-11-20 20:22:22 -05:00
parent c8c95bfb47
commit 3e8bee4f65
4 changed files with 121 additions and 61 deletions
+6 -2
View File
@@ -26,7 +26,7 @@ import {
import createAdminStore from './store/createAdminStore'
import { i18nProvider } from './i18n'
import config from './config'
import { startEventStream } from './eventStream'
import { setDispatch, startEventStream } from './eventStream'
const history = createHashHistory()
@@ -60,7 +60,11 @@ const App = () => (
const Admin = (props) => {
const dispatch = useDispatch()
if (config.devActivityMenu) {
startEventStream(dispatch)
setDispatch(dispatch)
authProvider
.checkAuth()
.then(() => startEventStream())
.catch(() => {}) // ignore if not logged in
}
return (
+6 -1
View File
@@ -1,8 +1,9 @@
import jwtDecode from 'jwt-decode'
import md5 from 'md5-hex'
import { v4 as uuidv4 } from 'uuid'
import { baseUrl } from './utils'
import config from './config'
import { v4 as uuidv4 } from 'uuid'
import { startEventStream, stopEventStream } from './eventStream'
const authProvider = {
login: ({ username, password }) => {
@@ -38,6 +39,9 @@ const authProvider = {
)
// Avoid going to create admin dialog after logout/login without a refresh
config.firstTime = false
startEventStream().catch((e) =>
console.log('error setting up event stream:', e)
)
return response
})
.catch((error) => {
@@ -53,6 +57,7 @@ const authProvider = {
},
logout: () => {
stopEventStream()
removeItems()
return Promise.resolve()
},
+47 -26
View File
@@ -1,19 +1,24 @@
import { baseUrl } from './utils'
import throttle from 'lodash.throttle'
import { processEvent, serverDown } from './actions'
import { httpClient } from './dataProvider'
import { REST_URL } from './consts'
let es = null
let dispatch = null
let timeout = null
const defaultIntervalCheck = 20000
const reconnectIntervalCheck = 2000
let currentIntervalCheck = reconnectIntervalCheck
let es = null
let dispatch = null
let timeout = null
const getEventStream = () => {
const getEventStream = async () => {
if (es === null) {
es = new EventSource(
baseUrl(`/app/api/events?jwt=${localStorage.getItem('token')}`)
)
return httpClient(`${REST_URL}/keepalive/`).then(() => {
es = new EventSource(
baseUrl(`/app/api/events?jwt=${localStorage.getItem('token')}`)
)
return es
})
}
return es
}
@@ -33,29 +38,45 @@ const setTimeout = (value) => {
}, currentIntervalCheck)
}
export const startEventStream = (dispatchFunc) => {
const stopEventStream = () => {
if (es) {
es.close()
}
es = null
if (timeout != null) {
window.clearTimeout(timeout)
}
timeout = null
}
const setDispatch = (dispatchFunc) => {
dispatch = dispatchFunc
}
const startEventStream = async () => {
setTimeout(currentIntervalCheck)
if (!localStorage.getItem('token')) {
console.log('Cannot create a unauthenticated EventSource connection')
return
}
const es = getEventStream()
es.onmessage = throttle(
(msg) => {
const data = JSON.parse(msg.data)
if (data.name !== 'keepAlive') {
dispatch(processEvent(data))
}
setTimeout(defaultIntervalCheck) // Reset timeout on every received message
},
100,
{ trailing: true }
)
es.onerror = (e) => {
setTimeout(reconnectIntervalCheck)
dispatch(serverDown())
}
return es
getEventStream().then((newStream) => {
newStream.onmessage = throttle(
(msg) => {
const data = JSON.parse(msg.data)
if (data.name !== 'keepAlive') {
dispatch(processEvent(data))
}
setTimeout(defaultIntervalCheck) // Reset timeout on every received message
},
100,
{ trailing: true }
)
newStream.onerror = (e) => {
setTimeout(reconnectIntervalCheck)
dispatch(serverDown())
}
es = newStream
})
}
export { setDispatch, startEventStream, stopEventStream }