From 9e9c928081e7219106ee456a728d684a9bd0693b Mon Sep 17 00:00:00 2001 From: yusuf Date: Fri, 29 Nov 2024 14:34:20 +0800 Subject: [PATCH 1/4] feat: change cache to use Map instead of Set. String is the feature name. --- lib/src/flagsmith_client.dart | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/src/flagsmith_client.dart b/lib/src/flagsmith_client.dart index 09b67ee..e327d6c 100644 --- a/lib/src/flagsmith_client.dart +++ b/lib/src/flagsmith_client.dart @@ -1,10 +1,11 @@ import 'dart:async'; import 'dart:convert'; + import 'package:collection/collection.dart' show IterableExtension; +import 'package:dio/dio.dart'; import 'package:flutter_client_sse/constants/sse_request_type_enum.dart'; import 'package:flutter_client_sse/flutter_client_sse.dart'; import 'package:rxdart/subjects.dart'; -import 'package:dio/dio.dart'; import '../flagsmith.dart'; @@ -35,10 +36,10 @@ class FlagsmithClient { late StorageProvider storageProvider; CoreStorage? storage; late Dio _api; - final Set _flags = {}; + final Map _flags = {}; final List seeds; - Set get cachedFlags => _flags; + Map get cachedFlags => _flags; //A map of flag names to the amount of times they have been evaluated in the last 10 seconds final Map flagAnalytics = {}; @@ -290,9 +291,8 @@ class FlagsmithClient { throw FlagsmithConfigException(Exception('caches are NOT enabled!')); } - var feature = _flags.firstWhereOrNull((element) => - element.feature.name == featureName && element.enabled == true); - return feature != null; + final feature = cachedFlags[featureName]; + return feature?.enabled == true; } /// Check if Feature flag exist and is enabled @@ -336,8 +336,7 @@ class FlagsmithClient { log('Exception: caches are NOT enabled!'); throw FlagsmithConfigException(Exception('caches are NOT enabled!')); } - var feature = cachedFlags - .firstWhereOrNull((element) => element.feature.name == featureId); + final feature = cachedFlags[featureId]; _incrementFlagAnalytics(feature); return feature?.stateValue; } @@ -357,7 +356,7 @@ class FlagsmithClient { Future removeFeatureFlag(String featureName) async { var result = await storageProvider.delete(featureName); if (config.caches) { - _flags.removeWhere((element) => element.feature.name == featureName); + _flags.removeWhere((key, _) => key == featureName); } return result; } @@ -539,11 +538,17 @@ class FlagsmithClient { /// Internal updadte caches from list of featurs void _updateCaches({List list = const []}) { - if (config.caches) { - _flags - ..clear() - ..addAll(list.toSet()); + if (!config.caches) { + return; + } + final newData = {}; + for (var element in list) { + newData[element.feature.name] = element; } + + _flags + ..clear() + ..addAll(newData); } /// clear all data from storage @@ -575,9 +580,9 @@ class FlagsmithClient { final result = await storageProvider.togggleFeature(featureName); final value = await storageProvider.read(featureName); if (config.caches) { - _flags.removeWhere((element) => element.feature.name == featureName); + _flags.removeWhere((key, _) => key == featureName); if (value != null) { - _flags.add(value); + _flags[value.feature.name] = value; } } return result; From 922998660f64a4c07f01bf47009ff10d8f5023e7 Mon Sep 17 00:00:00 2001 From: Evandro Myller <22429+emyller@users.noreply.github.com> Date: Tue, 26 Aug 2025 21:24:37 -0300 Subject: [PATCH 2/4] Improve cleaning up cache --- lib/src/flagsmith_client.dart | 2 +- test/fg/flagsmith_caches_test.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/flagsmith_client.dart b/lib/src/flagsmith_client.dart index e327d6c..f995dba 100644 --- a/lib/src/flagsmith_client.dart +++ b/lib/src/flagsmith_client.dart @@ -356,7 +356,7 @@ class FlagsmithClient { Future removeFeatureFlag(String featureName) async { var result = await storageProvider.delete(featureName); if (config.caches) { - _flags.removeWhere((key, _) => key == featureName); + _flags.remove(featureName); } return result; } diff --git a/test/fg/flagsmith_caches_test.dart b/test/fg/flagsmith_caches_test.dart index 6e56067..28b164a 100644 --- a/test/fg/flagsmith_caches_test.dart +++ b/test/fg/flagsmith_caches_test.dart @@ -57,6 +57,7 @@ void main() { var result = await fs.removeFeatureFlag(featureName); expect(result, true); + expect(fs.cachedFlags.containsKey(featureName), false); final removed = await fs.hasFeatureFlag(featureName); expect(removed, false); From ce70a3a5867a393d7a5625c25c598e4e61f5067e Mon Sep 17 00:00:00 2001 From: Evandro Myller <22429+emyller@users.noreply.github.com> Date: Tue, 26 Aug 2025 21:37:56 -0300 Subject: [PATCH 3/4] Improve testToggle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What is testToggle though? 🤔 --- lib/src/flagsmith_client.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/src/flagsmith_client.dart b/lib/src/flagsmith_client.dart index f995dba..3076f19 100644 --- a/lib/src/flagsmith_client.dart +++ b/lib/src/flagsmith_client.dart @@ -578,11 +578,10 @@ class FlagsmithClient { /// Future testToggle(String featureName) async { final result = await storageProvider.togggleFeature(featureName); - final value = await storageProvider.read(featureName); if (config.caches) { - _flags.removeWhere((key, _) => key == featureName); + final value = await storageProvider.read(featureName); if (value != null) { - _flags[value.feature.name] = value; + _flags[featureName] = value; } } return result; From b7d61c7452d15f681c94ae3a15aef9d821baccd6 Mon Sep 17 00:00:00 2001 From: Evandro Myller Date: Tue, 26 Aug 2025 22:10:46 -0300 Subject: [PATCH 4/4] Improve _updateCaches --- lib/src/flagsmith_client.dart | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/src/flagsmith_client.dart b/lib/src/flagsmith_client.dart index 3076f19..94f3232 100644 --- a/lib/src/flagsmith_client.dart +++ b/lib/src/flagsmith_client.dart @@ -541,14 +541,8 @@ class FlagsmithClient { if (!config.caches) { return; } - final newData = {}; - for (var element in list) { - newData[element.feature.name] = element; - } - - _flags - ..clear() - ..addAll(newData); + _flags.clear(); + _flags.addEntries(list.map((flag) => MapEntry(flag.feature.name, flag))); } /// clear all data from storage