First draft of non-monolithic state tree updater thing. Needs realworld testing
parent
e4b40a23ae
commit
46711ba87e
|
@ -51,7 +51,7 @@
|
|||
"css-loader": "2.1.0",
|
||||
"enzyme": "3.8.0",
|
||||
"enzyme-adapter-react-16": "1.7.1",
|
||||
"farmbot": "7.0.0-rc1",
|
||||
"farmbot": "7.0.0-rc2",
|
||||
"farmbot-toastr": "1.0.3",
|
||||
"fastclick": "1.0.6",
|
||||
"file-loader": "3.0.1",
|
||||
|
|
|
@ -20,7 +20,7 @@ jest.mock("../../../config_storage/actions", () => {
|
|||
|
||||
import { HardwareState } from "../../../devices/interfaces";
|
||||
import {
|
||||
incomingStatus,
|
||||
incomingLegacyStatus,
|
||||
actOnChannelName,
|
||||
showLogOnScreen,
|
||||
TITLE,
|
||||
|
@ -56,8 +56,8 @@ describe("readStatus()", () => {
|
|||
describe("incomingStatus", () => {
|
||||
it("creates an action", () => {
|
||||
const stub = {} as HardwareState;
|
||||
const result = incomingStatus(stub);
|
||||
expect(result.type).toEqual(Actions.BOT_CHANGE);
|
||||
const result = incomingLegacyStatus(stub);
|
||||
expect(result.type).toEqual(Actions.LEGACY_BOT_CHANGE);
|
||||
expect(result.payload).toEqual(stub);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,6 +25,7 @@ import { BooleanSetting } from "../session_keys";
|
|||
import { versionOK } from "../util";
|
||||
import { onLogs } from "./log_handlers";
|
||||
import { ChannelName } from "../sequences/interfaces";
|
||||
import { DeepPartial } from "redux";
|
||||
|
||||
export const TITLE = "New message from bot";
|
||||
/** TODO: This ought to be stored in Redux. It is here because of historical
|
||||
|
@ -36,8 +37,11 @@ export const HACKY_FLAGS = {
|
|||
|
||||
/** Action creator that is called when FarmBot OS emits a status update.
|
||||
* Coordinate updates, movement, etc.*/
|
||||
export let incomingStatus = (statusMessage: HardwareState) =>
|
||||
({ type: Actions.BOT_CHANGE, payload: statusMessage });
|
||||
export const incomingLegacyStatus = (statusMessage: HardwareState) =>
|
||||
({ type: Actions.LEGACY_BOT_CHANGE, payload: statusMessage });
|
||||
|
||||
export const incomingStatus =
|
||||
(payload: DeepPartial<HardwareState>) => ({ type: Actions.STATUS_UPDATE, payload });
|
||||
|
||||
/** Determine if an incoming log has a certain channel. If it is, execute the
|
||||
* supplied callback. */
|
||||
|
@ -106,20 +110,40 @@ export const changeLastClientConnected = (bot: Farmbot) => () => {
|
|||
"LAST_CLIENT_CONNECTED": JSON.stringify(new Date())
|
||||
}).catch(() => { }); // This is internal stuff, don't alert user.
|
||||
};
|
||||
const onStatus = (dispatch: Function, getState: GetState) =>
|
||||
(throttle(function (msg: BotStateTree) {
|
||||
bothUp("Got a status message");
|
||||
|
||||
/** Too many status updates === too many screen redraws. */
|
||||
const slowDown = (fn: (...args: unknown[]) => unknown) =>
|
||||
throttle(fn, 600, { leading: false, trailing: true });
|
||||
|
||||
const setBothUp = () => bothUp("Got a status message");
|
||||
|
||||
const legacyChecks = (getState: GetState) => {
|
||||
if (HACKY_FLAGS.needVersionCheck) {
|
||||
const IS_OK = versionOK(getState()
|
||||
.bot
|
||||
.hardware
|
||||
.informational_settings
|
||||
.controller_version, EXPECTED_MAJOR, EXPECTED_MINOR);
|
||||
if (!IS_OK) { badVersion(); }
|
||||
HACKY_FLAGS.needVersionCheck = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** Legacy handler for bots that have not upgraded to FBOS v7 yet.
|
||||
* - RC 21 JAN 18 */
|
||||
const onLegacyStatus =
|
||||
(dispatch: Function, getState: GetState) => slowDown((msg: BotStateTree) => {
|
||||
setBothUp();
|
||||
dispatch(incomingLegacyStatus(msg));
|
||||
legacyChecks(getState);
|
||||
});
|
||||
|
||||
const onStatus =
|
||||
(dispatch: Function, getState: GetState) => slowDown((msg: DeepPartial<BotStateTree>) => {
|
||||
setBothUp();
|
||||
dispatch(incomingStatus(msg));
|
||||
if (HACKY_FLAGS.needVersionCheck) {
|
||||
const IS_OK = versionOK(getState()
|
||||
.bot
|
||||
.hardware
|
||||
.informational_settings
|
||||
.controller_version, EXPECTED_MAJOR, EXPECTED_MINOR);
|
||||
if (!IS_OK) { badVersion(); }
|
||||
HACKY_FLAGS.needVersionCheck = false;
|
||||
}
|
||||
}, 600, { leading: false, trailing: true }));
|
||||
legacyChecks(getState);
|
||||
});
|
||||
|
||||
type Client = { connected?: boolean };
|
||||
|
||||
|
@ -152,6 +176,7 @@ const attachEventListeners =
|
|||
bot.on("offline", onOffline);
|
||||
bot.on("sent", onSent(bot.client));
|
||||
bot.on("logs", onLogs(dispatch, getState));
|
||||
bot.on("legacy_status", onLegacyStatus(dispatch, getState));
|
||||
bot.on("status", onStatus(dispatch, getState));
|
||||
bot.on("malformed", onMalformed);
|
||||
bot.client.on("message", autoSync(dispatch, getState));
|
||||
|
|
|
@ -704,7 +704,9 @@ export enum Actions {
|
|||
CHANGE_STEP_SIZE = "CHANGE_STEP_SIZE",
|
||||
SETTING_UPDATE_START = "SETTING_UPDATE_START",
|
||||
SETTING_UPDATE_END = "SETTING_UPDATE_END",
|
||||
BOT_CHANGE = "BOT_CHANGE",
|
||||
/** Used in FBOS < v7. Remove ASAP. RC 21 JAN 18 */
|
||||
LEGACY_BOT_CHANGE = "LEGACY_BOT_CHANGE",
|
||||
STATUS_UPDATE = "STATUS_UPDATE",
|
||||
FETCH_OS_UPDATE_INFO_OK = "FETCH_OS_UPDATE_INFO_OK",
|
||||
FETCH_OS_UPDATE_INFO_ERROR = "FETCH_OS_UPDATE_INFO_ERROR",
|
||||
FETCH_BETA_OS_UPDATE_INFO_OK = "FETCH_BETA_OS_UPDATE_INFO_OK",
|
||||
|
|
|
@ -84,7 +84,7 @@ describe("botReducer", () => {
|
|||
payload.location_data.position.x = -1;
|
||||
payload.location_data.position.y = -1;
|
||||
payload.location_data.position.z = -1;
|
||||
const action = { type: Actions.BOT_CHANGE, payload };
|
||||
const action = { type: Actions.LEGACY_BOT_CHANGE, payload };
|
||||
// Make the starting state different than initialState();
|
||||
const result = botReducer(state, action);
|
||||
// Resets .hardware to initialState()
|
||||
|
|
|
@ -10,6 +10,7 @@ import { ReduxAction } from "../redux/interfaces";
|
|||
import { connectivityReducer } from "../connectivity/reducer";
|
||||
import { versionOK } from "../util";
|
||||
import { EXPECTED_MAJOR, EXPECTED_MINOR } from "./actions";
|
||||
import { DeepPartial } from "redux";
|
||||
|
||||
const afterEach = (state: BotState, a: ReduxAction<{}>) => {
|
||||
state.connectivity = connectivityReducer(state.connectivity, a);
|
||||
|
@ -126,36 +127,11 @@ export let botReducer = generateReducer<BotState>(initialState(), afterEach)
|
|||
s.minOsFeatureData = payload;
|
||||
return s;
|
||||
})
|
||||
.add<HardwareState>(Actions.BOT_CHANGE, (state, { payload }) => {
|
||||
state.hardware = payload;
|
||||
const { informational_settings } = state.hardware;
|
||||
const syncStatus = informational_settings.sync_status;
|
||||
/** USE CASE: You reboot the bot. The old state values are still hanging
|
||||
* around. You think the bot is broke, but it isn't. The FE is holding on
|
||||
* to stale data. */
|
||||
if (syncStatus === "maintenance") {
|
||||
const emptyState = initialState();
|
||||
state.hardware = emptyState.hardware;
|
||||
state.hardware.informational_settings.sync_status = "maintenance";
|
||||
return state;
|
||||
}
|
||||
|
||||
const info = {
|
||||
consistent: state.consistent,
|
||||
syncStatus,
|
||||
fbosVersion: informational_settings.controller_version,
|
||||
autoSync: !!state.hardware.configuration.auto_sync
|
||||
};
|
||||
state.consistent = info.consistent;
|
||||
info.consistent = state.consistent;
|
||||
|
||||
const nextSyncStatus = maybeNegateStatus(info);
|
||||
|
||||
versionOK(informational_settings.controller_version,
|
||||
EXPECTED_MAJOR, EXPECTED_MINOR);
|
||||
state.hardware.informational_settings.sync_status = nextSyncStatus;
|
||||
return state;
|
||||
.add<DeepPartial<HardwareState>>(Actions.STATUS_UPDATE, (s, { payload }) => {
|
||||
const nextState = { ...s, ...payload };
|
||||
return nextState;
|
||||
})
|
||||
.add<HardwareState>(Actions.LEGACY_BOT_CHANGE, legacyStatusHandler)
|
||||
.add<void>(Actions.STASH_STATUS, (s) => {
|
||||
stash(s);
|
||||
return s;
|
||||
|
@ -189,3 +165,36 @@ const stash = (s: BotState) => {
|
|||
/** Put the old syncStatus back where it was after bot becomes consistent. */
|
||||
const unstash = (s: BotState) =>
|
||||
s.hardware.informational_settings.sync_status = s.statusStash;
|
||||
|
||||
function legacyStatusHandler(state: BotState,
|
||||
action: ReduxAction<HardwareState>): BotState {
|
||||
const { payload } = action;
|
||||
state.hardware = payload;
|
||||
const { informational_settings } = state.hardware;
|
||||
const syncStatus = informational_settings.sync_status;
|
||||
/** USE CASE: You reboot the bot. The old state values are still hanging
|
||||
* around. You think the bot is broke, but it isn't. The FE is holding on
|
||||
* to stale data. */
|
||||
if (syncStatus === "maintenance") {
|
||||
const emptyState = initialState();
|
||||
state.hardware = emptyState.hardware;
|
||||
state.hardware.informational_settings.sync_status = "maintenance";
|
||||
return state;
|
||||
}
|
||||
|
||||
const info = {
|
||||
consistent: state.consistent,
|
||||
syncStatus,
|
||||
fbosVersion: informational_settings.controller_version,
|
||||
autoSync: !!state.hardware.configuration.auto_sync
|
||||
};
|
||||
state.consistent = info.consistent;
|
||||
info.consistent = state.consistent;
|
||||
|
||||
const nextSyncStatus = maybeNegateStatus(info);
|
||||
|
||||
versionOK(informational_settings.controller_version,
|
||||
EXPECTED_MAJOR, EXPECTED_MINOR);
|
||||
state.hardware.informational_settings.sync_status = nextSyncStatus;
|
||||
return state;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue