hub/reducers: consolidate command in progress states

The Loaded state is not used anywhere else, so we can replace it with
the Unknown state. Then we can make all other command-in-progress
states (start repl/stop user program) the same as download and run.
When the command completes, the hub is in an unknown state until a
status message is received. The Disconnected states overrides all other
states.
This commit is contained in:
David Lechner
2023-04-01 13:38:19 -05:00
committed by David Lechner
parent ce29984be5
commit 69605ada4a
2 changed files with 98 additions and 11 deletions
+69 -3
View File
@@ -16,6 +16,8 @@ import {
didStartDownload,
hubDidFailToStartRepl,
hubDidFailToStopUserProgram,
hubDidStartRepl,
hubDidStopUserProgram,
hubStartRepl,
hubStopUserProgram,
} from './actions';
@@ -111,7 +113,7 @@ describe('runtime', () => {
expect(
reducers({ runtime: HubRuntimeState.Loading } as State, didFinishDownload())
.runtime,
).toBe(HubRuntimeState.Loaded);
).toBe(HubRuntimeState.Unknown);
});
test('didFinishDownload', () => {
@@ -153,7 +155,7 @@ describe('runtime', () => {
// normal operation - user program started
expect(
reducers(
{ runtime: HubRuntimeState.Loaded } as State,
{ runtime: HubRuntimeState.Unknown } as State,
didReceiveStatusReport(statusToFlag(Status.UserProgramRunning)),
).runtime,
).toBe(HubRuntimeState.Running);
@@ -161,7 +163,7 @@ describe('runtime', () => {
// really short program run finished before receiving download finished
expect(
reducers(
{ runtime: HubRuntimeState.Loaded } as State,
{ runtime: HubRuntimeState.Unknown } as State,
didReceiveStatusReport(0),
).runtime,
).toBe(HubRuntimeState.Idle);
@@ -173,6 +175,22 @@ describe('runtime', () => {
didReceiveStatusReport(0),
).runtime,
).toBe(HubRuntimeState.Idle);
// ignored during start repl command
expect(
reducers(
{ runtime: HubRuntimeState.StartingRepl } as State,
didReceiveStatusReport(0),
).runtime,
).toBe(HubRuntimeState.StartingRepl);
// ignored during stop user program command
expect(
reducers(
{ runtime: HubRuntimeState.StoppingUserProgram } as State,
didReceiveStatusReport(0),
).runtime,
).toBe(HubRuntimeState.StoppingUserProgram);
});
test('hubStartRepl', () => {
@@ -182,6 +200,21 @@ describe('runtime', () => {
).toBe(HubRuntimeState.StartingRepl);
});
test('hubDidStartRepl', () => {
expect(
reducers({ runtime: HubRuntimeState.Running } as State, hubDidStartRepl())
.runtime,
).toBe(HubRuntimeState.Unknown);
// ignored if disconnected
expect(
reducers(
{ runtime: HubRuntimeState.Disconnected } as State,
hubDidStartRepl(),
).runtime,
).toBe(HubRuntimeState.Disconnected);
});
test('hubDidFailToStartRepl', () => {
expect(
reducers(
@@ -189,6 +222,14 @@ describe('runtime', () => {
hubDidFailToStartRepl(),
).runtime,
).toBe(HubRuntimeState.Unknown);
// ignored if disconnected
expect(
reducers(
{ runtime: HubRuntimeState.Disconnected } as State,
hubDidFailToStartRepl(),
).runtime,
).toBe(HubRuntimeState.Disconnected);
});
test('hubStopUserProgram', () => {
@@ -200,6 +241,23 @@ describe('runtime', () => {
).toBe(HubRuntimeState.StoppingUserProgram);
});
test('hubStopUserProgram', () => {
expect(
reducers(
{ runtime: HubRuntimeState.Running } as State,
hubDidStopUserProgram(),
).runtime,
).toBe(HubRuntimeState.Unknown);
// ignored if disconnected
expect(
reducers(
{ runtime: HubRuntimeState.Disconnected } as State,
hubDidStopUserProgram(),
).runtime,
).toBe(HubRuntimeState.Disconnected);
});
test('hubDidFailToStopUserProgram', () => {
expect(
reducers(
@@ -207,5 +265,13 @@ describe('runtime', () => {
hubDidFailToStopUserProgram(),
).runtime,
).toBe(HubRuntimeState.Unknown);
// ignored if disconnected
expect(
reducers(
{ runtime: HubRuntimeState.Disconnected } as State,
hubDidFailToStopUserProgram(),
).runtime,
).toBe(HubRuntimeState.Disconnected);
});
});
+29 -8
View File
@@ -28,6 +28,8 @@ import {
didStartDownload,
hubDidFailToStartRepl,
hubDidFailToStopUserProgram,
hubDidStartRepl,
hubDidStopUserProgram,
hubStartRepl,
hubStopUserProgram,
} from './actions';
@@ -44,8 +46,6 @@ export enum HubRuntimeState {
Idle = 'hub.runtime.idle',
/** A user program is being copied to the hub. */
Loading = 'hub.runtime.loading',
/** A user program has been copied to the hub. */
Loaded = 'hub.runtime.loaded',
/** A user program is running. */
Running = 'hub.runtime.running',
/** Busy starting the REPL. */
@@ -84,7 +84,8 @@ const runtime: Reducer<HubRuntimeState> = (
if (state === HubRuntimeState.Disconnected) {
return state;
}
return HubRuntimeState.Loaded;
// state is unknown until we receive a status event
return HubRuntimeState.Unknown;
}
if (didFailToFinishDownload.matches(action)) {
@@ -100,7 +101,9 @@ const runtime: Reducer<HubRuntimeState> = (
// let the hub status interfere with it.
if (
state === HubRuntimeState.Disconnected ||
state === HubRuntimeState.Loading
state === HubRuntimeState.Loading ||
state === HubRuntimeState.StartingRepl ||
state === HubRuntimeState.StoppingUserProgram
) {
return state;
}
@@ -116,10 +119,19 @@ const runtime: Reducer<HubRuntimeState> = (
return HubRuntimeState.StartingRepl;
}
// NB: hubDidStartRepl will trigger user program running, so we don't
// change state for both to avoid race condition
if (hubDidStartRepl.matches(action)) {
if (state === HubRuntimeState.Disconnected) {
return state;
}
// state is unknown until we receive a status event
return HubRuntimeState.Unknown;
}
if (hubDidFailToStartRepl.matches(action)) {
if (state === HubRuntimeState.Disconnected) {
return state;
}
// failed to communicate, so state is unknown
return HubRuntimeState.Unknown;
}
@@ -127,10 +139,19 @@ const runtime: Reducer<HubRuntimeState> = (
return HubRuntimeState.StoppingUserProgram;
}
// NB: hubDidStopUserProgram will trigger user program running flag to clear,
// so we don't change state for both to avoid race condition
if (hubDidStopUserProgram.matches(action)) {
if (state === HubRuntimeState.Disconnected) {
return state;
}
// state is unknown until we receive a status event
return HubRuntimeState.Unknown;
}
if (hubDidFailToStopUserProgram.matches(action)) {
if (state === HubRuntimeState.Disconnected) {
return state;
}
// failed to communicate, so state is unknown
return HubRuntimeState.Unknown;
}