From 417a9968b7cf8f77b67e76e3a78f6395d6418ccb Mon Sep 17 00:00:00 2001 From: Tamal Patra Date: Sat, 9 May 2020 22:38:24 +0530 Subject: [PATCH] #22 - new util: ReadyOrNotMixin --- src/sprightly/lib/models/dao.dart | 24 ++--- src/sprightly/lib/models/db/database.dart | 105 ++++++++------------- src/sprightly/lib/utils/file_provider.dart | 57 ++++++----- src/sprightly/lib/utils/ready_or_not.dart | 24 +++++ 4 files changed, 100 insertions(+), 110 deletions(-) create mode 100644 src/sprightly/lib/utils/ready_or_not.dart diff --git a/src/sprightly/lib/models/dao.dart b/src/sprightly/lib/models/dao.dart index 2d1e1b0..a93b45f 100644 --- a/src/sprightly/lib/models/dao.dart +++ b/src/sprightly/lib/models/dao.dart @@ -1,32 +1,24 @@ library sprightly.dao; +import 'dart:async'; + import 'package:package_info/package_info.dart'; import 'package:sprightly/models/constants/enums.dart'; import 'package:sprightly/models/db/database.dart'; +import 'package:sprightly/utils/ready_or_not.dart'; String get groupAccountPrefix => 'GroupAccount'; abstract class AppDao { bool get ready; - Future getReady(); + FutureOr getReady(); } -class AppInformation extends AppDao { - bool _initialized = false; - bool _working = false; - Future _worker; +class AppInformation with ReadyOrNotMixin { PackageInfo packageInfo; - @override - bool get ready => _initialized; - @override - Future getReady() async { - if (!_initialized && !_working) { - _working = true; - _worker = PackageInfo.fromPlatform(); - packageInfo = await _worker; - _initialized = true; - _working = false; - } else if (_working) await _worker; + + AppInformation() { + getReadyWorker = PackageInfo.fromPlatform; } String get appName => packageInfo.appName; diff --git a/src/sprightly/lib/models/db/database.dart b/src/sprightly/lib/models/db/database.dart index 01d0010..7fbb4f1 100644 --- a/src/sprightly/lib/models/db/database.dart +++ b/src/sprightly/lib/models/db/database.dart @@ -10,6 +10,7 @@ import 'package:sprightly/models/constants/enums.dart'; import 'package:sprightly/models/dao.dart'; import 'package:sprightly/utils/file_provider.dart'; import 'package:sprightly/utils/happy_hash.dart'; +import 'package:sprightly/utils/ready_or_not.dart'; part 'database.g.dart'; @@ -458,13 +459,13 @@ class CustomQuery { bool get isLoaded => (_query ?? '').isNotEmpty; } -class SprightlyQueries { - static SprightlyQueries universal = SprightlyQueries(); +class SprightlyQueries with ReadyOrNotMixin { + static SprightlyQueries universal = SprightlyQueries._(); + SprightlyQueries._() { + getReadyWorker = _getReady; + } factory SprightlyQueries() => universal; - bool initialized = false; - bool _working = false; - // startup queries CustomQuery get defaultStartupStatement => CustomQuery.fromAsset("defaultStartupStatement.sql"); @@ -494,34 +495,25 @@ class SprightlyQueries { // 'https://example.com/some/source/setupMigrationFrom1.sql'), }; - Future _init() async { - if (!initialized && !_working) { - _working = true; - try { - // Required for fetching file from web - await RemoteFileCache.universal.init(); - - // custom queries - await selectGroupAccountMembers.load(); - await selectGroupOnlyMembers.load(); - await selectGroupSettlements.load(); - await selectGroupTransactions.load(); - - initialized = true; - } finally { - _working = false; - } - } + Future _getReady() async { + // Required for fetching file from web + await RemoteFileCache.universal.getReady(); + + // custom queries + await selectGroupAccountMembers.load(); + await selectGroupOnlyMembers.load(); + await selectGroupSettlements.load(); + await selectGroupTransactions.load(); } } mixin _GenericDaoMixin on DatabaseAccessor { SprightlyQueries _queries = SprightlyQueries.universal; - bool get ready => _queries.initialized; + bool get _daoMixinReady => _queries.ready; - Future getReady() async { - await _queries._init(); + Future _getDaoMixinReady() async { + await _queries.getReady(); await customStatement(await _queries.defaultStartupStatement.load()); } @@ -605,26 +597,18 @@ mixin _GenericDaoMixin on DatabaseAccessor { ], ) class SprightlyDao extends DatabaseAccessor - with _$SprightlyDaoMixin, _GenericDaoMixin + with _$SprightlyDaoMixin, _GenericDaoMixin, ReadyOrNotMixin implements SystemDao { - SprightlyDao(SprightlyDatabase _db) : super(_db); + SprightlyDao(SprightlyDatabase _db) : super(_db) { + getReadyWorker = _getReady; + } - bool _initialized = false; - bool _working = false; - @override - bool get ready => super.ready && _initialized; @override - Future getReady() async { - if (!_initialized && !_working) { - _working = true; - try { - await super.getReady(); - _sharedGroupList = await getGroups(GroupType.Shared); - _initialized = true; - } finally { - _working = false; - } - } + bool get ready => super._daoMixinReady && super.ready; + + Future _getReady() async { + await super._getDaoMixinReady(); + _sharedGroupList = await getGroups(GroupType.Shared); } @override @@ -1097,30 +1081,23 @@ class SprightlyDao extends DatabaseAccessor ], ) class SprightlySetupDao extends DatabaseAccessor - with _$SprightlySetupDaoMixin, _GenericDaoMixin + with _$SprightlySetupDaoMixin, _GenericDaoMixin, ReadyOrNotMixin implements SettingsDao { - SprightlySetupDao(SprightlySetupDatabase _db) : super(_db); + SprightlySetupDao(SprightlySetupDatabase _db) : super(_db) { + getReadyWorker = _getReady; + } - bool _initialized = false; - bool _working = false; - @override - bool get ready => super.ready && _appInformation.ready && _initialized; @override - Future getReady() async { - if (!_initialized && !_working) { - _working = true; - try { - await super.getReady(); - await _appInformation.getReady(); - _allAppSettings = await getAppSettings(); - _allAppFonts = await getAppFonts(); - _allFontCombos = await getFontCombos(); - _allColorCombos = await getColorCombos(); - _initialized = true; - } finally { - _working = false; - } - } + bool get ready => + super._daoMixinReady && _appInformation.ready && super.ready; + + Future _getReady() async { + await super._getDaoMixinReady(); + await _appInformation.getReady(); + _allAppSettings = await getAppSettings(); + _allAppFonts = await getAppFonts(); + _allFontCombos = await getFontCombos(); + _allColorCombos = await getColorCombos(); } @override diff --git a/src/sprightly/lib/utils/file_provider.dart b/src/sprightly/lib/utils/file_provider.dart index a1b2ee4..9bcdd02 100644 --- a/src/sprightly/lib/utils/file_provider.dart +++ b/src/sprightly/lib/utils/file_provider.dart @@ -13,6 +13,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:sprightly/extensions/file_system_entity_extensions.dart'; import 'package:sprightly/extensions/http_response_extensions.dart'; import 'package:sprightly/utils/formatted_exception.dart'; +import 'package:sprightly/utils/ready_or_not.dart'; String get _moduleName => 'file_provider'; int get maxCachedRetentionMins => 7 * 24 * 60; // 7 days @@ -274,8 +275,11 @@ FormattedException _formattedException( moduleName: _moduleName, ); -class RemoteFileCache { - static RemoteFileCache universal = RemoteFileCache(); +class RemoteFileCache with ReadyOrNotMixin { + static RemoteFileCache universal = RemoteFileCache._(); + RemoteFileCache._() { + getReadyWorker = _getReady; + } factory RemoteFileCache() => universal; final String _cacheDirectory = '__fileCache'; @@ -286,35 +290,28 @@ class RemoteFileCache { DirectoryInfo _directoryInfo; DirectoryInfo get directoryInfo => _directoryInfo; - bool initialized = false; + @override + bool get ready => _ready && super.ready; + bool _ready = false; bool _working = false; - Future init() async { - if (!initialized && !_working) { - _working = true; - try { - var cacheDirectory = await getDirectory(_cacheDirectory); - if (await cacheDirectory.exists()) { - var oldFileCache = - await getFileText(p.join(_cacheDirectory, _cacheFile)); - if (null != oldFileCache) - _fileCache - ..clear() - ..addAll(json.decode(oldFileCache)); - } else - await cacheDirectory.create(recursive: true); - - // non-essential for startup. let it be on its own. - // i.e. not await(ing) - compute(DirectoryInfo.readDirectory, cacheDirectory).then((info) { - _directoryInfo = info; - initialized = true; - }).whenComplete(() => _working = false); - } catch (error) { - _working = false; - rethrow; - } - } + Future _getReady() async { + var cacheDirectory = await getDirectory(_cacheDirectory); + if (await cacheDirectory.exists()) { + var oldFileCache = await getFileText(p.join(_cacheDirectory, _cacheFile)); + if (null != oldFileCache) + _fileCache + ..clear() + ..addAll(json.decode(oldFileCache)); + } else + await cacheDirectory.create(recursive: true); + + // non-essential for startup. let it be on its own. + // i.e. not await(ing) + compute(DirectoryInfo.readDirectory, cacheDirectory).then((info) { + _directoryInfo = info; + _ready = true; + }); } /// Fetch the file from the [source] url and store in a the local [_cacheDirectory]. @@ -463,7 +460,7 @@ class RemoteFileCache { } Future cleanUp() async { - if (initialized && !_working) { + if (ready && !_working) { _working = true; return _cleanFileCache().whenComplete(() => DirectoryInfo.cleanUp(_DirectoryCleanUp(_directoryInfo, _fileCache)) diff --git a/src/sprightly/lib/utils/ready_or_not.dart b/src/sprightly/lib/utils/ready_or_not.dart new file mode 100644 index 0000000..acc7d3b --- /dev/null +++ b/src/sprightly/lib/utils/ready_or_not.dart @@ -0,0 +1,24 @@ +import 'dart:async'; + +typedef FutureOr ReadyOrNotWorker(); + +mixin ReadyOrNotMixin { + bool _initialized = false; + bool _working = false; + Future _future; + ReadyOrNotWorker getReadyWorker; + + bool get ready => _initialized; + FutureOr getReady() async { + if (!_initialized && !_working) { + _working = true; + try { + _future = getReadyWorker(); + await _future; + _initialized = true; + } finally { + _working = false; + } + } else if (_working) await _future; + } +}