integrate exiting state into state machine

pull/2/head
fuwa 5 years ago
parent 1331c36ac6
commit 628cfa07b6

@ -80,5 +80,5 @@ Stream<String> runBinary (String name, {Stream<String> input}) async* {
// the app should never reach here // the app should never reach here
log.info('Daemon exited gracefully.'); log.info('Daemon exited gracefully.');
exit(0); // exit(0);
} }

@ -131,13 +131,24 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
SyncingState _syncingState = await _loadingState.next(loading, ''); SyncingState _syncingState = await _loadingState.next(loading, '');
final syncing = process.runBinary(binName, input: inputStreamController.stream).asBroadcastStream(); final syncing = process
.runBinary(binName, input: inputStreamController.stream)
.asBroadcastStream();
SyncedState _syncedState = await _syncingState.next(inputStreamController.sink, syncing, _isExiting); HookedState _syncedNextState = await _syncingState.next(inputStreamController.sink, syncing);
await _syncedState.next();
var validState = true;
var exited = false; var exited = false;
if (_syncedNextState is SyncedState) {
SyncedState _syncedState = _syncedNextState;
await _syncedState.next();
} else {
ExitingState _exitingState = _syncedNextState;
await _exitingState.wait();
exited = true;
}
var validState = true;
while (validState && !exited) { while (validState && !exited) {
await _getState().use await _getState().use
( (
@ -148,12 +159,18 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
(s) => s.next(), (s) => s.next(),
(s) { (s) {
s.wait(); s.wait();
log.finer('exit state wait done');
exited = true; exited = true;
} }
); );
} }
if (!exited) { log.finer('state machine finished');
if (exited) {
log.finer('popping navigator');
SystemNavigator.pop();
} else {
log.severe('Reached invalid state!'); log.severe('Reached invalid state!');
exit(1); exit(1);
} }
@ -168,7 +185,7 @@ class _CyberWOW_PageState extends State<CyberWOW_Page> with WidgetsBindingObserv
SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]);
BlankState _blankState = BlankState(_setState, _getNotification); BlankState _blankState = BlankState(_setState, _getNotification, _isExiting);
_state = _blankState; _state = _blankState;
buildStateMachine(_blankState); buildStateMachine(_blankState);

@ -72,11 +72,13 @@ abstract class AppState {
typedef SetStateFunc = void Function(AppState); typedef SetStateFunc = void Function(AppState);
typedef GetNotificationFunc = AppLifecycleState Function(); typedef GetNotificationFunc = AppLifecycleState Function();
typedef IsExitingFunc = bool Function();
class HookedState extends AppState { class HookedState extends AppState {
final SetStateFunc setState; final SetStateFunc setState;
final GetNotificationFunc getNotification; final GetNotificationFunc getNotification;
HookedState(this.setState, this.getNotification); final IsExitingFunc isExiting;
HookedState(this.setState, this.getNotification, this.isExiting);
syncState() { syncState() {
setState(this); setState(this);
@ -89,10 +91,10 @@ class HookedState extends AppState {
} }
class BlankState extends HookedState { class BlankState extends HookedState {
BlankState(f, s) : super (f, s); BlankState(f1, f2, f3) : super (f1, f2, f3);
Future<LoadingState> next(String status) async { Future<LoadingState> next(String status) async {
LoadingState _next = LoadingState(setState, getNotification, status); LoadingState _next = LoadingState(setState, getNotification, isExiting, status);
return moveState(_next); return moveState(_next);
} }
} }
@ -101,7 +103,7 @@ class LoadingState extends HookedState {
String banner; String banner;
String status = ''; String status = '';
LoadingState(f, s, this.banner) : super (f, s); LoadingState(f1, f2, f3, this.banner) : super (f1, f2, f3);
void append(String msg) { void append(String msg) {
this.status += msg; this.status += msg;
@ -141,7 +143,7 @@ class LoadingState extends HookedState {
await Future.wait([load(), showBanner()]); await Future.wait([load(), showBanner()]);
} }
SyncingState _next = SyncingState(setState, getNotification); SyncingState _next = SyncingState(setState, getNotification, isExiting);
return moveState(_next); return moveState(_next);
} }
} }
@ -150,7 +152,7 @@ class SyncingState extends HookedState {
Queue<String> stdout = Queue(); Queue<String> stdout = Queue();
bool synced = false; bool synced = false;
SyncingState(f, s) : super (f, s); SyncingState(f1, f2, f3) : super (f1, f2, f3);
void append(String msg) { void append(String msg) {
stdout.addLast(msg); stdout.addLast(msg);
@ -160,9 +162,9 @@ class SyncingState extends HookedState {
syncState(); syncState();
} }
Future<SyncedState> next Future<HookedState> next
( (
StreamSink<String> processInput, Stream<String> processOutput, IsExitingFunc isExiting StreamSink<String> processInput, Stream<String> processOutput
) async { ) async {
log.fine("Syncing next"); log.fine("Syncing next");
@ -180,6 +182,11 @@ class SyncingState extends HookedState {
await for (final _null in refresh.pull(getNotification, 'syncingState')) { await for (final _null in refresh.pull(getNotification, 'syncingState')) {
log.finer('SyncingState: checkSync loop'); log.finer('SyncingState: checkSync loop');
if (isExiting()) {
log.fine('Syncing state detected exiting');
break;
}
// here doc is wrong, targetHeight could match height when synced // here doc is wrong, targetHeight could match height when synced
// potential bug, targetHeight could be smaller then height // potential bug, targetHeight could be smaller then height
final _isConnected = await daemon.isConnected(); final _isConnected = await daemon.isConnected();
@ -195,6 +202,14 @@ class SyncingState extends HookedState {
printStdout(); printStdout();
await checkSync(); await checkSync();
if (isExiting()) {
ExitingState _next = ExitingState
(
setState, getNotification, isExiting, stdout, processOutput
);
return moveState(_next);
}
log.fine('syncing: loop exit'); log.fine('syncing: loop exit');
// processInput.add('exit'); // processInput.add('exit');
@ -206,8 +221,6 @@ class SyncingState extends HookedState {
} }
} }
typedef IsExitingFunc = bool Function();
class SyncedState extends HookedState { class SyncedState extends HookedState {
Queue<String> stdout; Queue<String> stdout;
int height; int height;
@ -219,16 +232,15 @@ class SyncedState extends HookedState {
String syncInfo = 'syncInfo'; String syncInfo = 'syncInfo';
List<dynamic> getConnections = []; List<dynamic> getConnections = [];
List<dynamic> getTransactionPool = []; List<dynamic> getTransactionPool = [];
final IsExitingFunc isExiting;
SyncedState(f, s, this.isExiting, this.stdout, this.processInput, this.processOutput) : super (f, s); SyncedState(f1, f2, f3, this.stdout, this.processInput, this.processOutput) : super (f1, f2, f3);
void appendInput(String line) { void appendInput(String line) {
stdout.addLast('> ' + line + '\n'); stdout.addLast('> ' + line + '\n');
processInput.add(line); processInput.add(line);
} }
Future<ReSyncingState> next() async { Future<HookedState> next() async {
log.fine("Synced next"); log.fine("Synced next");
Future<void> logStdout() async { Future<void> logStdout() async {
@ -247,12 +259,7 @@ class SyncedState extends HookedState {
await for (final _null in refresh.pull(getNotification, 'syncedState')) { await for (final _null in refresh.pull(getNotification, 'syncedState')) {
if (isExiting()) { if (isExiting()) {
log.fine('Synced state detected exiting'); log.fine('Synced state detected exiting');
break;
ExitingState _next = ExitingState
(
setState, getNotification, stdout, processOutput
);
return moveState(_next);
} }
if (await daemon.isNotSynced()) { if (await daemon.isNotSynced()) {
@ -278,6 +285,14 @@ class SyncedState extends HookedState {
await checkSync(); await checkSync();
if (isExiting()) {
ExitingState _next = ExitingState
(
setState, getNotification, isExiting, stdout, processOutput
);
return moveState(_next);
}
log.fine('synced: loop exit'); log.fine('synced: loop exit');
ReSyncingState _next = ReSyncingState ReSyncingState _next = ReSyncingState
@ -294,9 +309,8 @@ class ReSyncingState extends HookedState {
StreamSink<String> processInput; StreamSink<String> processInput;
Stream<String> processOutput; Stream<String> processOutput;
bool synced = false; bool synced = false;
final IsExitingFunc isExiting;
ReSyncingState(f, s, this.isExiting, this.stdout, this.processInput, this.processOutput) : super (f, s); ReSyncingState(f1, f2, f3, this.stdout, this.processInput, this.processOutput) : super (f1, f2, f3);
void append(String msg) { void append(String msg) {
stdout.addLast(msg); stdout.addLast(msg);
@ -306,7 +320,7 @@ class ReSyncingState extends HookedState {
syncState(); syncState();
} }
Future<SyncedState> next() async { Future<HookedState> next() async {
log.fine("ReSyncing next"); log.fine("ReSyncing next");
Future<void> printStdout() async { Future<void> printStdout() async {
@ -320,6 +334,10 @@ class ReSyncingState extends HookedState {
Future<void> checkSync() async { Future<void> checkSync() async {
await for (final _null in refresh.pull(getNotification, 'ReSyncingState')) { await for (final _null in refresh.pull(getNotification, 'ReSyncingState')) {
if (isExiting()) {
log.fine('ReSyncing state detected exiting');
break;
}
if (await daemon.isSynced()) { if (await daemon.isSynced()) {
synced = true; synced = true;
@ -332,6 +350,14 @@ class ReSyncingState extends HookedState {
printStdout(); printStdout();
await checkSync(); await checkSync();
if (isExiting()) {
ExitingState _next = ExitingState
(
setState, getNotification, isExiting, stdout, processOutput
);
return moveState(_next);
}
log.fine('resync: await exit'); log.fine('resync: await exit');
SyncedState _next = SyncedState SyncedState _next = SyncedState
( (
@ -346,7 +372,7 @@ class ExitingState extends HookedState {
Queue<String> stdout; Queue<String> stdout;
Stream<String> processOutput; Stream<String> processOutput;
ExitingState(f, s, this.stdout, this.processOutput) : super (f, s); ExitingState(f1, f2, f3, this.stdout, this.processOutput) : super (f1, f2, f3);
void append(String msg) { void append(String msg) {
stdout.addLast(msg); stdout.addLast(msg);
@ -361,7 +387,7 @@ class ExitingState extends HookedState {
Future<void> printStdout() async { Future<void> printStdout() async {
await for (final line in processOutput) { await for (final line in processOutput) {
log.finest('exiting: print stdout loop'); log.info('exiting: print stdout loop');
append(line); append(line);
log.info(line); log.info(line);
@ -369,5 +395,7 @@ class ExitingState extends HookedState {
} }
await printStdout(); await printStdout();
log.info('exiting state done');
} }
} }