Skip to content

Commit

Permalink
added ping timeout, adjusted config loading and logging
Browse files Browse the repository at this point in the history
  • Loading branch information
gallayl committed Jun 2, 2024
1 parent d2553ad commit 3518195
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 16 deletions.
49 changes: 42 additions & 7 deletions common/schemas/config-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -487,10 +492,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -556,10 +566,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -620,10 +635,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -843,10 +863,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -1003,10 +1028,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -1120,10 +1150,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down
14 changes: 12 additions & 2 deletions common/schemas/config-entities.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down Expand Up @@ -194,10 +199,15 @@
"pingIntervalMs": {
"type": "number",
"description": "The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes)."
},
"pingTimeoutMs": {
"type": "number",
"description": "The timeout in milliseconds for each ping request. Defaults to 3000 (3 second)."
}
},
"required": [
"pingIntervalMs"
"pingIntervalMs",
"pingTimeoutMs"
],
"additionalProperties": false
}
Expand Down
5 changes: 5 additions & 0 deletions common/src/models/config/iot-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,10 @@ export interface IotConfig {
* The interval in milliseconds at which to ping all IOT devices to check their availability. Defaults to 120000 (2 minutes).
*/
pingIntervalMs: number

/**
* The timeout in milliseconds for each ping request. Defaults to 3000 (3 second).
*/
pingTimeoutMs: number
}
}
34 changes: 27 additions & 7 deletions service/src/iot/device-availability-hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ import { Config, Device, DevicePingHistory } from 'common'
import ping from 'ping'
import type { IotConfig } from '../../../common/src/models/config/iot-config.js'

const defaultIotConfig: IotConfig = {
id: 'IOT_CONFIG',
value: {
pingIntervalMs: 30 * 1000,
pingTimeoutMs: 3000,
},
}

@Injectable({ lifetime: 'singleton' })
export class DeviceAvailabilityHub extends EventHub<{ connected: Device; disconnected: Device; refresh: null }> {
private devices: Device[] = []
Expand All @@ -22,15 +30,30 @@ export class DeviceAvailabilityHub extends EventHub<{ connected: Device; disconn
@Injected((injector) => injector.getInstance(StoreManager).getStoreFor(Config, 'id'))
private declare configStore: PhysicalStore<Config, 'id', WithOptionalId<Config, 'id'>>

private getCurrentConfig = async () => {
try {
const loaded = (await this.configStore.get('IOT_CONFIG')) as IotConfig
return loaded || defaultIotConfig
} catch (error) {
await this.logger.warning({
message: 'Error while loading IOT_CONFIG, falling back to defaults',
data: { error },
})
return defaultIotConfig
}
}

private async refreshConnections() {
this.emit('refresh', null)
const currentConfig = await this.getCurrentConfig()

try {
await this.devices
.filter((device) => device.ipAddress)
.map(async (device) => {
const lastStatus = this.deviceStatusMap.get(device.name)
const { alive: newStatus, avg } = await ping.promise.probe(device.ipAddress!, {
timeout: 1,
timeout: currentConfig.value.pingTimeoutMs,
})

if (lastStatus !== newStatus) {
Expand All @@ -51,8 +74,9 @@ export class DeviceAvailabilityHub extends EventHub<{ connected: Device; disconn
data: { error },
})
} finally {
const currentConfig = (await this.configStore.get('IOT_CONFIG')) as IotConfig
await sleepAsync(currentConfig?.value.pingIntervalMs || 120 * 1000)
const sleepMs = currentConfig.value.pingIntervalMs || 30 * 1000
await this.logger.verbose({ message: `Device refresh done, sleeping for ${sleepMs}ms` })
await sleepAsync(sleepMs)
await this.refreshConnections()
}
}
Expand Down Expand Up @@ -80,10 +104,6 @@ export class DeviceAvailabilityHub extends EventHub<{ connected: Device; disconn
this.deviceStore.subscribe('onEntityUpdated', ({ id, change }) => {
this.updateDevices(this.devices.map((device) => (device.name === id ? { ...device, ...change } : device)))
})
}

constructor() {
super()
this.refreshConnections()
}
}

0 comments on commit 3518195

Please sign in to comment.