diff --git a/frontend/__tests__/interceptors_test.ts b/frontend/__tests__/interceptors_test.ts index ef81060a1..d1a8995d0 100644 --- a/frontend/__tests__/interceptors_test.ts +++ b/frontend/__tests__/interceptors_test.ts @@ -31,8 +31,6 @@ import { dispatchNetworkUp, dispatchNetworkDown } from "../connectivity"; import { Session } from "../session"; import { error } from "../toast/toast"; -const A_STRING = expect.any(String); - interface FakeProps { uuid: string; method: Method; @@ -67,7 +65,7 @@ describe("responseRejected", () => { it("undefined error", async () => { await expect(responseRejected(undefined)).rejects.toEqual(undefined); expect(dispatchNetworkUp).not.toHaveBeenCalled(); - expect(dispatchNetworkDown).toHaveBeenCalledWith("user.api", undefined, A_STRING); + expect(dispatchNetworkDown).toHaveBeenCalledWith("user.api"); }); it("safe error", async () => { @@ -77,7 +75,7 @@ describe("responseRejected", () => { }; await expect(responseRejected(safeError)).rejects.toEqual(safeError); expect(dispatchNetworkDown).not.toHaveBeenCalled(); - expect(dispatchNetworkUp).toHaveBeenCalledWith("user.api", undefined, A_STRING); + expect(dispatchNetworkUp).toHaveBeenCalledWith("user.api"); }); it("handles 500", async () => { diff --git a/frontend/connectivity/__tests__/connect_device/index_test.ts b/frontend/connectivity/__tests__/connect_device/index_test.ts index 93501987c..cab29d82c 100644 --- a/frontend/connectivity/__tests__/connect_device/index_test.ts +++ b/frontend/connectivity/__tests__/connect_device/index_test.ts @@ -42,7 +42,6 @@ import { MessageType } from "../../../sequences/interfaces"; import { FbjsEventName } from "farmbot/dist/constants"; import { info, error, success, warning, fun, busy } from "../../../toast/toast"; -const A_STRING = expect.any(String); describe("readStatus()", () => { it("forces a read_status request to FarmBot", () => { readStatus(); @@ -160,9 +159,9 @@ describe("initLog", () => { describe("bothUp()", () => { it("marks MQTT and API as up", () => { - bothUp("tests"); - expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt", undefined, A_STRING); - expect(dispatchNetworkUp).toHaveBeenCalledWith("bot.mqtt", undefined, A_STRING); + bothUp(); + expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt"); + expect(dispatchNetworkUp).toHaveBeenCalledWith("bot.mqtt"); }); }); @@ -170,7 +169,7 @@ describe("onOffline", () => { it("tells the app MQTT is down", () => { jest.resetAllMocks(); onOffline(); - expect(dispatchNetworkDown).toHaveBeenCalledWith("user.mqtt", undefined, A_STRING); + expect(dispatchNetworkDown).toHaveBeenCalledWith("user.mqtt"); expect(error).toHaveBeenCalledWith(Content.MQTT_DISCONNECTED); }); }); @@ -179,7 +178,7 @@ describe("onOnline", () => { it("tells the app MQTT is up", () => { jest.resetAllMocks(); onOnline(); - expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt", undefined, A_STRING); + expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt"); }); }); @@ -205,13 +204,13 @@ describe("onSent", () => { it("marks MQTT as up", () => { jest.resetAllMocks(); onSent({ connected: true })(); - expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt", undefined, A_STRING); + expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt"); }); it("marks MQTT as down", () => { jest.resetAllMocks(); onSent({ connected: false })(); - expect(dispatchNetworkDown).toHaveBeenCalledWith("user.mqtt", undefined, A_STRING); + expect(dispatchNetworkDown).toHaveBeenCalledWith("user.mqtt"); }); }); @@ -235,7 +234,7 @@ describe("onLogs", () => { log.message = "bot xyz is offline"; fn(log); globalQueue.maybeWork(); - expect(dispatchNetworkDown).toHaveBeenCalledWith("bot.mqtt", undefined, A_STRING); + expect(dispatchNetworkDown).toHaveBeenCalledWith("bot.mqtt"); }); it("handles log fields correctly", () => { diff --git a/frontend/connectivity/__tests__/index_test.ts b/frontend/connectivity/__tests__/index_test.ts index ead834a90..d77e3aa4c 100644 --- a/frontend/connectivity/__tests__/index_test.ts +++ b/frontend/connectivity/__tests__/index_test.ts @@ -14,29 +14,29 @@ const SHORT_TIME_LATER = new Date(NOW.getTime() + 500).getTime(); const LONGER_TIME_LATER = new Date(NOW.getTime() + 5000).getTime(); describe("dispatchNetworkUp", () => { - const NOW_UP = networkUp("bot.mqtt", NOW.getTime(), "tests"); - const LATER_UP = networkUp("bot.mqtt", LONGER_TIME_LATER, "tests"); + const NOW_UP = networkUp("bot.mqtt", NOW.getTime()); + const LATER_UP = networkUp("bot.mqtt", LONGER_TIME_LATER); it("calls redux directly", () => { - dispatchNetworkUp("bot.mqtt", NOW.getTime(), "tests"); + dispatchNetworkUp("bot.mqtt", NOW.getTime()); expect(mockRedux.store.dispatch).toHaveBeenLastCalledWith(NOW_UP); - dispatchNetworkUp("bot.mqtt", SHORT_TIME_LATER, "tests"); + dispatchNetworkUp("bot.mqtt", SHORT_TIME_LATER); expect(mockRedux.store.dispatch).toHaveBeenLastCalledWith(NOW_UP); - dispatchNetworkUp("bot.mqtt", LONGER_TIME_LATER, "tests"); + dispatchNetworkUp("bot.mqtt", LONGER_TIME_LATER); expect(mockRedux.store.dispatch).toHaveBeenLastCalledWith(LATER_UP); }); }); describe("dispatchNetworkDown", () => { - const NOW_DOWN = networkDown("user.api", NOW.getTime(), "tests"); - const LATER_DOWN = networkDown("user.api", LONGER_TIME_LATER, "tests"); + const NOW_DOWN = networkDown("user.api", NOW.getTime()); + const LATER_DOWN = networkDown("user.api", LONGER_TIME_LATER); it("calls redux directly", () => { - dispatchNetworkDown("user.api", NOW.getTime(), "tests"); + dispatchNetworkDown("user.api", NOW.getTime()); expect(mockRedux.store.dispatch).toHaveBeenLastCalledWith(NOW_DOWN); - dispatchNetworkDown("user.api", SHORT_TIME_LATER, "tests"); + dispatchNetworkDown("user.api", SHORT_TIME_LATER); expect(mockRedux.store.dispatch).toHaveBeenLastCalledWith(NOW_DOWN); - dispatchNetworkDown("user.api", LONGER_TIME_LATER, "tests"); + dispatchNetworkDown("user.api", LONGER_TIME_LATER); expect(mockRedux.store.dispatch).toHaveBeenLastCalledWith(LATER_DOWN); }); }); diff --git a/frontend/connectivity/__tests__/ping_mqtt_test.ts b/frontend/connectivity/__tests__/ping_mqtt_test.ts index 0117e84db..f3b69eb79 100644 --- a/frontend/connectivity/__tests__/ping_mqtt_test.ts +++ b/frontend/connectivity/__tests__/ping_mqtt_test.ts @@ -1,6 +1,7 @@ jest.mock("../index", () => ({ dispatchNetworkDown: jest.fn(), - dispatchNetworkUp: jest.fn() + dispatchNetworkUp: jest.fn(), + dispatchQosStart: jest.fn() })); const mockTimestamp = 0; @@ -49,14 +50,14 @@ function fakeBot(): Farmbot { function expectStale() { expect(dispatchNetworkDown) - .toHaveBeenCalledWith("bot.mqtt", undefined, expect.any(String)); + .toHaveBeenCalledWith("bot.mqtt"); } function expectActive() { expect(dispatchNetworkUp) - .toHaveBeenCalledWith("bot.mqtt", undefined, expect.any(String)); + .toHaveBeenCalledWith("bot.mqtt"); expect(dispatchNetworkUp) - .toHaveBeenCalledWith("user.mqtt", undefined, expect.any(String)); + .toHaveBeenCalledWith("user.mqtt"); } describe("ping util", () => { @@ -67,12 +68,12 @@ describe("ping util", () => { }); it("marks the bot's connection to MQTT as 'stale'", () => { - markStale(); + markStale("TESTS"); expectStale(); }); it("marks the bot's connection to MQTT as 'active'", () => { - markActive(); + markActive("TESTS"); expectActive(); }); diff --git a/frontend/connectivity/__tests__/reducer_edge_status_test.ts b/frontend/connectivity/__tests__/reducer_edge_status_test.ts index b0cb349a5..35e352890 100644 --- a/frontend/connectivity/__tests__/reducer_edge_status_test.ts +++ b/frontend/connectivity/__tests__/reducer_edge_status_test.ts @@ -4,7 +4,7 @@ import { networkUp, networkDown } from "../actions"; describe("connectivityReducer", () => { it("goes up", () => { const state = connectivityReducer(DEFAULT_STATE, - networkUp("user.mqtt", undefined, "tests")); + networkUp("user.mqtt")); expect(state).toBeDefined(); const x = state && state.uptime["user.mqtt"]; if (x) { @@ -17,7 +17,7 @@ describe("connectivityReducer", () => { it("goes down", () => { const state = connectivityReducer(DEFAULT_STATE, - networkDown("user.api", undefined, "tests")); + networkDown("user.api")); const x = state && state.uptime["user.api"]; if (x) { expect(x.state).toBe("down"); diff --git a/frontend/connectivity/actions.ts b/frontend/connectivity/actions.ts index a42514f1c..c36982c10 100644 --- a/frontend/connectivity/actions.ts +++ b/frontend/connectivity/actions.ts @@ -5,10 +5,10 @@ import { ReduxAction } from "../redux/interfaces"; type NetChange = ReduxAction; const change = (state: "up" | "down") => - (name: Edge, at = (new Date()).getTime(), why: string): NetChange => { + (name: Edge, at = (new Date()).getTime(), qosPingId?: string): NetChange => { return { type: Actions.NETWORK_EDGE_CHANGE, - payload: { name, status: { state, at }, why } + payload: { name, status: { state, at }, qosPingId } }; }; diff --git a/frontend/connectivity/batch_queue.ts b/frontend/connectivity/batch_queue.ts index 1fe101d70..47c652c67 100644 --- a/frontend/connectivity/batch_queue.ts +++ b/frontend/connectivity/batch_queue.ts @@ -28,7 +28,7 @@ export class BatchQueue { store.dispatch(batchInitResources(this.queue)); } this.clear(); - bothUp("Inside BatchQueue instance"); + bothUp(); } push = (resource: TaggedLog) => { diff --git a/frontend/connectivity/connect_device.ts b/frontend/connectivity/connect_device.ts index cf408d5a5..e7f802e2b 100644 --- a/frontend/connectivity/connect_device.ts +++ b/frontend/connectivity/connect_device.ts @@ -95,9 +95,9 @@ export const batchInitResources = return { type: Actions.BATCH_INIT, payload }; }; -export const bothUp = (why: string) => { - dispatchNetworkUp("user.mqtt", undefined, why); - dispatchNetworkUp("bot.mqtt", undefined, why); +export const bothUp = () => { + dispatchNetworkUp("user.mqtt"); + dispatchNetworkUp("bot.mqtt"); }; export function readStatus() { @@ -108,7 +108,7 @@ export function readStatus() { } export const onOffline = () => { - dispatchNetworkDown("user.mqtt", undefined, "onOffline() callback"); + dispatchNetworkDown("user.mqtt"); error(t(Content.MQTT_DISCONNECTED)); }; @@ -117,7 +117,7 @@ export const changeLastClientConnected = (bot: Farmbot) => () => { "LAST_CLIENT_CONNECTED": JSON.stringify(new Date()) }).catch(noop); // This is internal stuff, don't alert user. }; -const setBothUp = () => bothUp("Got a status message"); +const setBothUp = () => bothUp(); const legacyChecks = (getState: GetState) => { const { controller_version } = getState().bot.hardware.informational_settings; @@ -150,13 +150,12 @@ type Client = { connected?: boolean }; export const onSent = (client: Client) => () => { const connected = !!client.connected; - const why = `Outbound mqtt.js. client.connected = ${connected}`; const cb = connected ? dispatchNetworkUp : dispatchNetworkDown; - cb("user.mqtt", undefined, why); + cb("user.mqtt"); }; export function onMalformed() { - bothUp("Got a malformed message"); + bothUp(); if (!HACKY_FLAGS.alreadyToldUserAboutMalformedMsg) { warning(t(Content.MALFORMED_MESSAGE_REC_UPGRADE)); HACKY_FLAGS.alreadyToldUserAboutMalformedMsg = true; @@ -166,11 +165,11 @@ export function onMalformed() { export const onOnline = () => { success(t("Reconnected to the message broker."), t("Online")); - dispatchNetworkUp("user.mqtt", undefined, "MQTT.js is online"); + dispatchNetworkUp("user.mqtt"); }; export const onReconnect = () => warning(t("Attempting to reconnect to the message broker"), - t("Offline"), "yellow"); + t("Offline"), "yellow"); export function onPublicBroadcast(payl: unknown) { console.log(FbjsEventName.publicBroadcast, payl); diff --git a/frontend/connectivity/index.ts b/frontend/connectivity/index.ts index 2913c4965..f037c62b5 100644 --- a/frontend/connectivity/index.ts +++ b/frontend/connectivity/index.ts @@ -1,6 +1,7 @@ import { store } from "../redux/store"; import { networkUp, networkDown } from "./actions"; import { Edge } from "./interfaces"; +import { Actions } from "../constants"; /* ABOUT THIS FILE: These functions allow us to mark the network as up or down from anywhere within the app (even outside of React-Redux). I usually avoid @@ -24,14 +25,23 @@ function bumpThrottle(edge: Edge, now: number) { lastCalledAt[edge] = now; } -export let dispatchNetworkUp = (edge: Edge, at = (new Date()).getTime(), why: string) => { +export const dispatchQosStart = (id: string) => { + store.dispatch({ + type: Actions.START_QOS_PING, + payload: { id } + }); +}; + +export let dispatchNetworkUp = (edge: Edge, at = (new Date()).getTime()) => { + console.log("TODO: Insert ID HERE"); if (shouldThrottle(edge, at)) { return; } - store.dispatch(networkUp(edge, at, why)); + store.dispatch(networkUp(edge, at)); bumpThrottle(edge, at); }; -export let dispatchNetworkDown = (edge: Edge, at = (new Date()).getTime(), why: string) => { +export let dispatchNetworkDown = (edge: Edge, at = (new Date()).getTime()) => { + console.log("TODO: Insert ID HERE"); if (shouldThrottle(edge, at)) { return; } - store.dispatch(networkDown(edge, at, why)); + store.dispatch(networkDown(edge, at)); bumpThrottle(edge, at); }; diff --git a/frontend/connectivity/interfaces.ts b/frontend/connectivity/interfaces.ts index 49aeb5130..919350303 100644 --- a/frontend/connectivity/interfaces.ts +++ b/frontend/connectivity/interfaces.ts @@ -11,7 +11,7 @@ export interface ConnectionStatus { export interface EdgeStatus { name: Edge; status: ConnectionStatus; - why: string; + qosPingId?: string; } /** Name of a connection between two points. "." can be read as "to". diff --git a/frontend/connectivity/log_handlers.ts b/frontend/connectivity/log_handlers.ts index 9a340a660..6741f0383 100644 --- a/frontend/connectivity/log_handlers.ts +++ b/frontend/connectivity/log_handlers.ts @@ -49,6 +49,6 @@ export const onLogs = // TODO: Make a `bot/device_123/offline` channel. const died = msg.message.includes("is offline") && msg.type === MessageType.error; - died && dispatchNetworkDown("bot.mqtt", undefined, "Got offline message"); + died && dispatchNetworkDown("bot.mqtt"); } }; diff --git a/frontend/connectivity/ping_mqtt.tsx b/frontend/connectivity/ping_mqtt.tsx index 3400c08c1..682bddc4e 100644 --- a/frontend/connectivity/ping_mqtt.tsx +++ b/frontend/connectivity/ping_mqtt.tsx @@ -1,5 +1,9 @@ -import { Farmbot } from "farmbot"; -import { dispatchNetworkDown, dispatchNetworkUp } from "./index"; +import { Farmbot, uuid } from "farmbot"; +import { + dispatchNetworkDown, + dispatchNetworkUp, + dispatchQosStart +} from "./index"; import { isNumber } from "lodash"; import axios from "axios"; import { API } from "../api/index"; @@ -17,13 +21,15 @@ export function readPing(bot: Farmbot, direction: Direction): number | undefined return isNumber(val) ? val : undefined; } -export function markStale() { - dispatchNetworkDown("bot.mqtt", undefined, "markStale()"); +export function markStale(_uuid: string) { + // dispatch({ pings: failPing(this.pingState, id) }) + dispatchNetworkDown("bot.mqtt"); } -export function markActive() { - dispatchNetworkUp("user.mqtt", undefined, "markActive()"); - dispatchNetworkUp("bot.mqtt", undefined, "markActive()"); +export function markActive(_uuid: string) { + // dispatch({ pings: completePing(this.pingState, id) }) + dispatchNetworkUp("user.mqtt"); + dispatchNetworkUp("bot.mqtt"); } export function isInactive(last: number, now: number): boolean { @@ -31,8 +37,12 @@ export function isInactive(last: number, now: number): boolean { } export function sendOutboundPing(bot: Farmbot) { - console.log("TODO"); - bot.ping().then(markActive, markStale); + const id = uuid(); + const ok = () => markActive(id); + const no = () => markStale(id); + dispatchQosStart(id); + setTimeout(no, PING_INTERVAL); + bot.ping().then(ok, no); } export function startPinging(bot: Farmbot) { @@ -41,7 +51,7 @@ export function startPinging(bot: Farmbot) { } export function pingAPI() { - const ok = () => dispatchNetworkUp("user.api", undefined, "pingApi OK"); - const no = () => dispatchNetworkDown("user.api", undefined, "pingApi NO"); + const ok = () => dispatchNetworkUp("user.api"); + const no = () => dispatchNetworkDown("user.api"); return axios.get(API.current.devicePath).then(ok, no); } diff --git a/frontend/connectivity/reducer.ts b/frontend/connectivity/reducer.ts index 4fbfa807f..360673fe3 100644 --- a/frontend/connectivity/reducer.ts +++ b/frontend/connectivity/reducer.ts @@ -5,6 +5,7 @@ import { computeBestTime } from "./reducer_support"; import { TaggedDevice } from "farmbot"; import { SyncBodyContents } from "../sync/actions"; import { arrayUnwrap } from "../resources/util"; +import { startPing, completePing, failPing } from "../devices/connectivity/qos"; export const DEFAULT_STATE: ConnectionState = { uptime: { @@ -18,8 +19,24 @@ export const DEFAULT_STATE: ConnectionState = { export let connectivityReducer = generateReducer(DEFAULT_STATE) + .add<{ id: string }>(Actions.START_QOS_PING, (s, { payload }) => { + return { + ...s, + pings: startPing(s.pings, payload.id) + }; + }) .add(Actions.NETWORK_EDGE_CHANGE, (s, { payload }) => { s.uptime[payload.name] = payload.status; + const { qosPingId, status } = payload; + if (qosPingId) { + if (status.state == "up") { + console.log("OK!!!"); + s.pings = completePing(s.pings, qosPingId, status.at); + } else { + console.log("FAILED"); + s.pings = failPing(s.pings, qosPingId); + } + } return s; }) .add>(Actions.RESOURCE_READY, (s, a) => { @@ -33,6 +50,7 @@ export let connectivityReducer = type Keys = (keyof ConnectionState["uptime"])[]; const keys: Keys = ["bot.mqtt", "user.mqtt", "user.api"]; keys.map(x => (s.uptime[x] = undefined)); + s.pings = {}; return s; }); diff --git a/frontend/constants.ts b/frontend/constants.ts index d1f764a48..c0406f9c7 100644 --- a/frontend/constants.ts +++ b/frontend/constants.ts @@ -994,5 +994,6 @@ export enum Actions { // Network NETWORK_EDGE_CHANGE = "NETWORK_EDGE_CHANGE", RESET_NETWORK = "RESET_NETWORK", - SET_CONSISTENCY = "SET_CONSISTENCY" + SET_CONSISTENCY = "SET_CONSISTENCY", + START_QOS_PING = "START_QOS_PING" } diff --git a/frontend/devices/__tests__/reducer_test.ts b/frontend/devices/__tests__/reducer_test.ts index 1d4f40b14..7a5398075 100644 --- a/frontend/devices/__tests__/reducer_test.ts +++ b/frontend/devices/__tests__/reducer_test.ts @@ -111,17 +111,17 @@ describe("botReducer", () => { step1.statusStash = "booting"; step1.hardware.informational_settings.sync_status = "synced"; - const step2 = botReducer(step1, networkDown("bot.mqtt", undefined, "tests")); + const step2 = botReducer(step1, networkDown("bot.mqtt")); expect(step2.statusStash) .toBe(step1.hardware.informational_settings.sync_status); expect(step2.hardware.informational_settings.sync_status).toBeUndefined(); - const step3 = botReducer(step1, networkDown("bot.mqtt", undefined, "tests")); + const step3 = botReducer(step1, networkDown("bot.mqtt")); expect(step3.statusStash) .toBe(step1.hardware.informational_settings.sync_status); expect(step3.hardware.informational_settings.sync_status).toBeUndefined(); - const step4 = botReducer(step3, networkUp("bot.mqtt", undefined, "tests")); + const step4 = botReducer(step3, networkUp("bot.mqtt")); expect(step4.hardware.informational_settings.sync_status) .toBe(step3.statusStash); }); diff --git a/frontend/devices/connectivity/qos.ts b/frontend/devices/connectivity/qos.ts index e303221bc..347a1563c 100644 --- a/frontend/devices/connectivity/qos.ts +++ b/frontend/devices/connectivity/qos.ts @@ -3,30 +3,32 @@ import { betterCompact } from "../../util"; interface Pending { kind: "pending"; id: string; - start: Date; - end?: undefined; + start: number; + end?: number; } interface Timeout { kind: "timeout"; id: string; - start: Date; - end?: undefined; + start: number; + end?: number; } interface Complete { kind: "complete"; id: string; - start: Date; - end: Date; + start: number; + end: number; } export type Ping = Complete | Pending | Timeout; export type PingDictionary = Record; +const now = () => (new Date()).getTime(); + export const startPing = - (s: PingDictionary, id: string): PingDictionary => { - return { ...s, [id]: { kind: "pending", id, start: new Date() } }; + (s: PingDictionary, id: string, start = now()): PingDictionary => { + return { ...s, [id]: { kind: "pending", id, start } }; }; export const failPing = @@ -45,7 +47,7 @@ export const failPing = }; export const completePing = - (s: PingDictionary, id: string): PingDictionary => { + (s: PingDictionary, id: string, end = now()): PingDictionary => { const failure = s[id]; if (failure && failure.kind == "pending") { return { @@ -54,7 +56,7 @@ export const completePing = kind: "complete", id, start: failure.start, - end: new Date() + end } }; } @@ -87,11 +89,8 @@ interface LatencyReport { total: number; } -const mapper = (p: Ping) => { - if (p.kind === "complete") { - return p.end.getTime() - p.start.getTime(); - } -}; +const mapper = (p: Ping) => (p.kind === "complete") ? + p.end - p.start : undefined; export const calculateLatency = (s: PingDictionary): LatencyReport => { diff --git a/frontend/devices/connectivity/qos_row.tsx b/frontend/devices/connectivity/qos_row.tsx new file mode 100644 index 000000000..de460dd91 --- /dev/null +++ b/frontend/devices/connectivity/qos_row.tsx @@ -0,0 +1,34 @@ +import { + calculateLatency, + calculatePingLoss, + PingDictionary, +} from "./qos"; +import React from "react"; + +interface Props { + pings: PingDictionary; +} + +export class QosRow extends React.Component { + get pingState(): PingDictionary { return this.props.pings; } + + render() { + const reportA = calculateLatency(this.pingState); + const reportB = calculatePingLoss(this.pingState); + const report = { ...reportA, ...reportB }; + const ber = ((report.complete || 0) / report.total) || 0; + return
+
+
    +
  • best: {report.best || 0}
  • +
  • worst: {report.worst || 0}
  • +
  • average: {(report.average || 0).toFixed(1)}
  • +
  • Pings OK: {report.complete}
  • +
  • Pings pending: {report.pending || 0}
  • +
  • Pings failed: {report.timeout || 0}
  • +
  • Total pings: {report.total || 0}
  • +
  • Percent OK: {(100 * ber).toFixed(1)}
  • +
+
; + } +} diff --git a/frontend/interceptors.ts b/frontend/interceptors.ts index aff16dd2d..b2b12d157 100644 --- a/frontend/interceptors.ts +++ b/frontend/interceptors.ts @@ -12,7 +12,7 @@ import { t } from "./i18next_wrapper"; import { error } from "./toast/toast"; export function responseFulfilled(input: AxiosResponse): AxiosResponse { - dispatchNetworkUp("user.api", undefined, "responseFulfilled()"); + dispatchNetworkUp("user.api"); return input; } @@ -26,7 +26,7 @@ export const isLocalRequest = (x: SafeError) => let ONLY_ONCE = true; export function responseRejected(x: SafeError | undefined) { if (x && isSafeError(x)) { - dispatchNetworkUp("user.api", undefined, "isSafeError() REST error"); + dispatchNetworkUp("user.api"); const a = ![451, 401, 422].includes(x.response.status); const b = x.response.status > 399; // Openfarm API was sending too many 404's. @@ -57,7 +57,7 @@ export function responseRejected(x: SafeError | undefined) { } return Promise.reject(x); } else { - dispatchNetworkDown("user.api", undefined, "responseRejected"); + dispatchNetworkDown("user.api"); return Promise.reject(x); } }