Skip to content

Commit

Permalink
core: frontend: Bridget: get rid of BridgetUpdater, only request data
Browse files Browse the repository at this point in the history
for prefetching or when there are listeners actively consuming it.

Co-authored-by: Patrick José Pereira <[email protected]>
Co-authored-by: Rafael Araujo Lehmkuhl <[email protected]>
  • Loading branch information
3 people committed Feb 21, 2022
1 parent f2655f7 commit f6d1134
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 74 deletions.
3 changes: 0 additions & 3 deletions core/frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@
<ethernet-updater />
<wifi-updater />
<mavlink-updater />
<bridget-updater />
<nmea-injector-updater />
<error-message />
</v-app>
Expand All @@ -155,7 +154,6 @@ import PowerMenu from './components/app/PowerMenu.vue'
import ReportMenu from './components/app/ReportMenu.vue'
import SettingsMenu from './components/app/SettingsMenu.vue'
import AutopilotManagerUpdater from './components/autopilot/AutopilotManagerUpdater.vue'
import BridgetUpdater from './components/bridges/BridgetUpdater.vue'
import EthernetTrayMenu from './components/ethernet/EthernetTrayMenu.vue'
import EthernetUpdater from './components/ethernet/EthernetUpdater.vue'
import HealthTrayMenu from './components/health/HealthTrayMenu.vue'
Expand All @@ -180,7 +178,6 @@ export default Vue.extend({
'health-tray-menu': HealthTrayMenu,
'mavlink-updater': MavlinkUpdater,
'nmea-injector-updater': NMEAInjectorUpdater,
'bridget-updater': BridgetUpdater,
'power-menu': PowerMenu,
'settings-menu': SettingsMenu,
'report-menu': ReportMenu,
Expand Down
5 changes: 4 additions & 1 deletion core/frontend/src/components/bridges/Bridget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<template v-for="(bridge, index) in available_bridges">
<v-divider
v-if="index!==0"
:key="index"
:key="`divider-${index}`"
/>
<v-list-item
:key="index"
Expand Down Expand Up @@ -94,6 +94,9 @@ export default Vue.extend({
return this.available_bridges.length !== 0
},
},
mounted() {
bridget.registerObject(this)
},
methods: {
openCreationDialog(): void {
this.show_creation_dialog = true
Expand Down
70 changes: 0 additions & 70 deletions core/frontend/src/components/bridges/BridgetUpdater.vue
Original file line number Diff line number Diff line change
@@ -1,70 +0,0 @@
<template>
<span />
</template>

<script lang="ts">
import Vue from 'vue'
import bridget from '@/store/bridget'
import notifications from '@/store/notifications'
import { bridget_service } from '@/types/frontend_services'
import back_axios, { backend_offline_error } from '@/utils/api'
import { callPeriodically } from '@/utils/helper_functions'
/**
* Responsible for updating bridget-related data.
* This component periodically fetches external APIs to gather information
* related to bridget functions, like bridges.
* @displayName Bridget Updater
*/
export default Vue.extend({
name: 'BridgetUpdater',
mounted() {
callPeriodically(this.fetchAvailableBridges, 5000)
callPeriodically(this.fetchAvailableSerialPorts, 5000)
},
methods: {
async fetchAvailableBridges(): Promise<void> {
back_axios({
method: 'get',
url: `${bridget.API_URL}/bridges`,
timeout: 10000,
})
.then((response) => {
const available_bridges = response.data
bridget.setAvailableBridges(available_bridges)
})
.catch((error) => {
bridget.setAvailableBridges([])
if (error === backend_offline_error) { return }
const message = `Could not fetch available bridges: ${error.message}`
notifications.pushError({ service: bridget_service, type: 'BRIDGES_FETCH_FAIL', message })
})
.finally(() => {
bridget.setUpdatingBridges(false)
})
},
async fetchAvailableSerialPorts(): Promise<void> {
back_axios({
method: 'get',
url: `${bridget.API_URL}/serial_ports`,
timeout: 10000,
})
.then((response) => {
const available_ports = response.data
bridget.setAvailableSerialPorts(available_ports)
})
.catch((error) => {
bridget.setAvailableSerialPorts([])
if (error === backend_offline_error) { return }
const message = `Could not fetch available serial ports: ${error.message}`
notifications.pushError({ service: bridget_service, type: 'BRIDGET_SERIAL_PORTS_FETCH_FAIL', message })
})
.finally(() => {
bridget.setUpdatingSerialPorts(false)
})
},
},
})
</script>
92 changes: 92 additions & 0 deletions core/frontend/src/store/bridget.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import {
Action,
getModule, Module, Mutation, VuexModule,
} from 'vuex-module-decorators'

import store from '@/store'
import notifications from '@/store/notifications'
import { Bridge } from '@/types/bridges'
import { bridget_service } from '@/types/frontend_services'
import back_axios, { backend_offline_error } from '@/utils/api'
import { callPeriodically } from '@/utils/helper_functions'

let prefetched_bridges = false
let prefetched_serial = false

@Module({
dynamic: true,
Expand All @@ -18,6 +26,8 @@ class BridgetStore extends VuexModule {

available_serial_ports: string[] = []

listener_number = 0

updating_bridges = true

updating_serial_ports = true
Expand All @@ -43,9 +53,91 @@ class BridgetStore extends VuexModule {
this.available_serial_ports = available_serial_ports
this.updating_bridges = false
}

@Mutation
registerListener(): void {
this.listener_number += 1
}

@Mutation
deregisterListener(): void {
if (this.listener_number <= 0) {
console.error('Deregister called with zero listeners.')
return
}
this.listener_number -= 1
}

@Action
async fetchAvailableBridges(): Promise<void> {
if (prefetched_bridges && !this.listener_number) {
return
}
back_axios({
method: 'get',
url: `${this.API_URL}/bridges`,
timeout: 10000,
})
.then((response) => {
const available_bridges = response.data
this.setAvailableBridges(available_bridges)
prefetched_bridges = true
})
.catch((error) => {
this.setAvailableBridges([])
if (error === backend_offline_error) { return }
const message = `Could not fetch available bridges: ${error.message}`
notifications.pushError({ service: bridget_service, type: 'BRIDGES_FETCH_FAIL', message })
})
.finally(() => {
this.setUpdatingBridges(false)
})
}

@Action
async fetchAvailableSerialPorts(): Promise<void> {
if (prefetched_serial && !this.listener_number) {
return
}
back_axios({
method: 'get',
url: `${this.API_URL}/serial_ports`,
timeout: 10000,
})
.then((response) => {
const available_ports = response.data
this.setAvailableSerialPorts(available_ports)
prefetched_serial = true
})
.catch((error) => {
this.setAvailableSerialPorts([])
if (error === backend_offline_error) { return }
const message = `Could not fetch available serial ports: ${error.message}`
notifications.pushError({ service: bridget_service, type: 'BRIDGET_SERIAL_PORTS_FETCH_FAIL', message })
})
.finally(() => {
this.setUpdatingSerialPorts(false)
})
}

@Action
async registerObject(object: any): Promise<void> {
this.registerListener()
const ref = new WeakRef(object)
const id = setInterval(() => {
// Check if object does not exist anymore or if it was destroyed by vue
// eslint-disable-next-line
if (!ref.deref() || ref.deref()._isDestroyed) {
this.deregisterListener()
clearInterval(id)
}
}, 1000)
}
}

export { BridgetStore }

const bridget: BridgetStore = getModule(BridgetStore)
callPeriodically(bridget.fetchAvailableBridges, 5000)
callPeriodically(bridget.fetchAvailableSerialPorts, 5000)
export default bridget

0 comments on commit f6d1134

Please sign in to comment.