WMSDK-595: Add queue for getDeviceUUID callbacks#180
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a queueing mechanism for getDeviceUUID (and related token) callbacks to prevent the SDK initialization from hanging when callbacks are pending. Previously, if a getDeviceUUID call was made before initialization and that callback didn't complete, the init method would block indefinitely. The changes allow init to complete by processing pending callbacks asynchronously rather than awaiting them.
Key Changes:
- Modified pending callback processing to use asynchronous
.then()chains instead ofawait, preventing init from blocking - Added subscription management using lists and atomic operations to handle multiple concurrent callback subscriptions safely
- Added comprehensive test coverage for the hanging callback scenario
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| mindbox_method_handler.dart | Changed pending callback processing from synchronous await to asynchronous .then() to prevent blocking during init |
| MindboxAndroidPlugin.kt | Refactored subscription handling from single variables to lists with atomic synchronization for thread-safe concurrent callback management |
| mindbox_method_handler_test.dart | Added test verifying init completes even when pending getDeviceUUID callbacks hang, enabling retry functionality |
Comments suppressed due to low confidence (1)
mindbox_android/android/src/main/kotlin/cloud/mindbox/mindbox_android/MindboxAndroidPlugin.kt:1
- The subscription lists are not thread-safe. Since callbacks may execute on different threads and you're using AtomicBoolean/AtomicReference for thread safety, these lists should also be synchronized. Consider using
Collections.synchronizedList(mutableListOf<String>())or implementing proper synchronization when accessing these lists to prevent concurrent modification exceptions.
package cloud.mindbox.mindbox_android
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| channel | ||
| .invokeMethod(callbackMethod.methodName) | ||
| .then((result) { | ||
| callbackMethod.callback(result ?? 'null'); | ||
| }).catchError((e) { | ||
| _logError('Error processing pending method ${callbackMethod.methodName}: $e'); | ||
| }); |
There was a problem hiding this comment.
The asynchronous callback processing creates a potential race condition where callbacks may execute after the init completes but before other state is fully initialized. Consider using unawaited() from dart:async to explicitly document that these futures are intentionally not awaited, which improves code clarity and helps prevent accidental regressions.
https://tracker.yandex.ru/agile/board/507