Last active
May 1, 2026 19:17
-
-
Save creativepsyco/ae6d03dba70d39a70bfee9738303ff79 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'dart:async'; | |
| // Simulates a slow async initialization | |
| Future<void> initializeRepositories() async { | |
| print(' ⏳ initializeRepositories: STARTED'); | |
| await Future.delayed(Duration(seconds: 2)); | |
| print(' ✅ initializeRepositories: DONE'); | |
| } | |
| // Simulates accountManager.run — note: it correctly awaits internally | |
| Future<void> accountManagerRun(Future<void> Function() action) async { | |
| print(' accountManager.run: calling action...'); | |
| await action(); | |
| print(' accountManager.run: action finished'); | |
| } | |
| void main() async { | |
| // Simulate a stream of session ID updates | |
| final controller = StreamController<String?>(); | |
| // ❌ BUG: listen() does NOT await the async callback. | |
| // The Future returned by the async callback is silently dropped. | |
| controller.stream.distinct().listen((sessionId) async { | |
| print('\n🔔 Event received: sessionId=$sessionId'); | |
| if (sessionId != null) { | |
| // This await only suspends THIS callback's microtask. | |
| // listen() itself has already returned void — nobody waits for this. | |
| await accountManagerRun(() async { | |
| await initializeRepositories(); | |
| }); | |
| } | |
| print('🏁 Callback for $sessionId thinks it is done.'); | |
| }); | |
| // Fire two events in quick succession | |
| print('>>> Emitting event 1: "user-abc"'); | |
| controller.add('user-abc'); | |
| print('>>> Emitting event 2: "user-xyz"'); | |
| controller.add('user-xyz'); | |
| // This runs IMMEDIATELY — it does NOT wait for the listen callbacks | |
| print('\n>>> Main continues WITHOUT waiting for initialization!'); | |
| print('>>> If code here assumes repos are initialized, 💥 RACE CONDITION.\n'); | |
| // Give time for the async callbacks to actually complete | |
| await Future.delayed(Duration(seconds: 5)); | |
| print('\n--- Timeline shows events interleaved, not sequential ---'); | |
| await controller.close(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment