kable
kable copied to clipboard
`connect()` freezes when invoked multiple times concurrently
I am using your library for quite some time now and never had this issue on Android. However, on iOS I rarely get the following error when the connection to my other device fails:
[DEBUG] ===== CONNECT =====
2022-06-08 16:47:23.481038+0200 Debug[1821:62982] I/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A Connecting
2022-06-08 16:47:23.702496+0200 Debug[1821:62982] Sentry - debug:: Add breadcrumb: <SentryBreadcrumb: 0x281878c80>
2022-06-08 16:47:23.823228+0200 Debug[1821:62982] D/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A CentralManagerDelegate state change
state: DidConnect(identifier=5DAB21AF-411C-3802-5F8A-ABDA17408F8A)
2022-06-08 16:47:23.823619+0200 Debug[1821:62982] V/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A discoverServices
2022-06-08 16:47:23.834300+0200 Debug[1821:62982] Sentry - debug:: Add breadcrumb: <SentryBreadcrumb: 0x281883380>
2022-06-08 16:47:24.586824+0200 Debug[1821:62982] Sentry - debug:: currentOrientation is unknown.
2022-06-08 16:47:25.159094+0200 Debug[1821:62982] I/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A Disconnected
2022-06-08 16:47:25.166130+0200 Debug[1821:62982] E/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A Failed to connect
kotlinx.coroutines.JobCancellationException: LazyDeferredCoroutine was cancelled; job=LazyDeferredCoroutine{Cancelling}@ab111d0
at 0 shared 0x10719d4cb kfun:kotlinx.coroutines.JobCancellationException#<init>(kotlin.String;kotlin.Throwable?;kotlinx.coroutines.Job){} + 179
at 1 shared 0x10714c107 kfun:kotlinx.coroutines.JobSupport#cancel(kotlin.coroutines.cancellation.CancellationException?){} + 203
at 2 shared 0x1071e09a3 kfun:com.juul.kable.ApplePeripheral.onDisconnected#internal + 647
at 3 shared 0x1071ed057 kfun:com.juul.kable.ApplePeripheral.$connectAsync$lambda-6$lambda-3COROUTINE$475.invokeSuspend#internal + 447
at 4 shared 0x1071ed2d3 kfun:com.juul.kable.ApplePeripheral.$connectAsync$lambda-6$lambda-3COROUTINE$475.invoke#interna
The call for peripheral.connect()
looks like this:
try {
Log.debug { "===== CONNECT =====" }
newPeripheral.connect()
Log.debug { "===== DONE =====" }
} catch(ex: Exception) {
Log.debug { "===== ERROR =====" }
Log.debug { "Connecting failed!\n" + ex.stackTraceToString() }
return@coroutineScope true
} finally {
Log.debug { "===== FINALLY =====" }
}
As you can see from the error message above, ===== CONNECT =====
is printed, by neither ===== ERROR =====
nor ===== FINALLY =====
appears, so I am assuming that connect()
never returns.
On iOS, I call this code from the UI thread. Do you have any idea why this might happen? When the connection can be established, everything works fine afterwards.
I think that I found the cause of the problem. The connect()
method was called two times in parallel. Depending of the execution speed and order, the call sometimes hung up and sometimes went through.
I think that I found the cause of the problem. The
connect()
method was called two times in parallel. Depending of the execution speed and order, the call sometimes hung up and sometimes went through.
Interesting. Re-opening, as connect
should support concurrent calls (i.e. it is a bug if it is stalling in that situation).
It may be a while before we can find time to prioritize fixing this. Thanks for the thorough issue report, it will really help when we do eventually get around to fixing this!
Although it is good to hear that you found a way to prevent the stalling.
Alright, thank you.
For comparison, here the connection also fails but the connect()
call does not block forever as above with the exact same code:
[DEBUG] ===== CONNECT =====
2022-06-08 17:09:30.175347+0200 Debug[1976:69737] I/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A Connecting
2022-06-08 17:09:30.532635+0200 Debug[1976:69737] D/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A CentralManagerDelegate state change
state: DidConnect(identifier=5DAB21AF-411C-3802-5F8A-ABDA17408F8A)
2022-06-08 17:09:30.533500+0200 Debug[1976:69737] V/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A discoverServices
2022-06-08 17:09:31.130085+0200 Debug[1976:70004] D/Kable/Delegate: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A 5DAB21AF-411C-3802-5F8A-ABDA17408F8A didDiscoverServices
2022-06-08 17:09:32.023419+0200 Debug[1976:69737] I/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A Disconnected
2022-06-08 17:09:32.023617+0200 Debug[1976:69737] D/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A CentralManagerDelegate state change
state: DidDisconnect(identifier=5DAB21AF-411C-3802-5F8A-ABDA17408F8A, error=Error Domain=CBErrorDomain Code=6 "The connection has timed out unexpectedly." UserInfo={NSLocalizedDescription=The connection has timed out unexpectedly.})
2022-06-08 17:09:32.038659+0200 Debug[1976:69737] E/Kable: 5DAB21AF-411C-3802-5F8A-ABDA17408F8A Failed to connect
kotlinx.coroutines.JobCancellationException: LazyDeferredCoroutine was cancelled; job=LazyDeferredCoroutine{Cancelling}@a081090
at 0 shared 0x1054ac56b kfun:kotlinx.coroutines.JobCancellationException#<init>(kotlin.String;kotlin.Throwable?;kotlinx.coroutines.Job){} + 179
at 1 shared 0x10545b1a7 kfun:kotlinx.coroutines.JobSupport#cancel(kotlin.coroutines.cancellation.CancellationException?){} + 203
at 2 shared 0x1054efa43 kfun:com.juul.kable.ApplePeripheral.onDisconnected#internal + 647
at 3 shared 0x1054fc0f7 kfun:com.juul.kable.ApplePeripheral.$connectAsync$lambda-6$lambda-3COROUTINE$477.invokeSuspend#internal + 447
at 4 shared 0x1054fc373 kfun:com.juul.kable.ApplePeripheral.$connectAsync$lambda-6$lambda-3COROUTINE$477.invoke#interna
[DEBUG] ===== ERROR =====
[DEBUG] Connecting failed!
kotlinx.coroutines.JobCancellationException: LazyDeferredCoroutine was cancelled; job=LazyDeferredCoroutine{Cancelled}@a081090
at 0 shared 0x1054ac56b kfun:kotlinx.coroutines.JobCancellationException#<init>(kotlin.String;kotlin.Throwable?;kotlinx.coroutines.Job){} + 179
at 1 shared 0x10545b1a7 kfun:kotlinx.coroutines.JobSupport#cancel(kotlin.coroutines.cancellation.CancellationException?){} + 203
at 2 shared 0x1054efa43 kfun:com.juul.kable.ApplePeripheral.onDisconnected#internal + 647
at 3 shared 0x1054fc0f7 kfun:com.juul.kable.ApplePeripheral.$connectAsync$lambda-6$lambda-3COROUTINE$477.invokeSuspend#internal + 447
at 4 shared 0x1054fc373 kfun:com.juul.kable.ApplePeripheral.$connectAsync$lambda-6$lambda-3COROUTINE$477.invoke#internal + 199
at 5 shared 0x105490f23 kfun:kotlinx.coroutines.flow.<no name provided>_1_1.$collect_2_2$<anonymous>_7_3COROUTINE$550.invokeSuspend#internal + 507
at 6 shared 0x1054911e3 kfun:kotlinx.coroutines.flow.<no name provided>_1_1.$collect_2_2$<anonymous>_7_3$FUNCTION_REFERENCE$469.emit#internal + 347
at 7 shared 0x10547f0a7 kfun:kotlinx.coroutines.flow.SharedFlowImpl.$collectCOROUTINE$524#invokeSuspend(kotlin.Result<kotlin.Any?>){}kotlin.Any? + 2535
at 8 shared 0x105383feb kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 295
at 9 shared 0x1054963fb kfun:kotlinx.coroutines.DispatchedTask#run(){} + 1527
at 10 shared 0x1054ae947 kfun:kotlinx.coroutines.DarwinMainDispatcher.$dispatch$<anonymous>_3$FUNCTION_REFERENCE$487.$<bridge-UNN>invoke(){}#internal + 307
at 11 shared 0x105acbd3f ___6f72672e6a6574627261696e732e6b6f746c696e783a6b6f746c696e782d636f726f7574696e65732d636f7265_knbridge835_block_invoke + 451
at 12 libdispatch.dylib 0x104600c6f _dispatch_call_block_and_release + 31
at 13 libdispatch.dylib 0x1046027bf _dispatch_client_callout + 19
at 14 libdispatch.dylib 0x104612c67 _dispatch_main_queue_drain + 1203
at 15 libdispatch.dylib 0x1046127a3 _dispatch_main_queue_callback_4CF + 43
at 16 CoreFoundation 0x1899f57ff <redacted> + 15
at 17 CoreFoundation 0x1899af703 <redacted> + 2531
at 18 CoreFoundation 0x1899c2bc7 CFRunLoopRunSpecific + 599
at 19 GraphicsServices 0x1a5af6373 GSEventRunModal + 163
at 20 UIKitCore 0x18c332647 <redacted> + 1099
at 21 UIKitCore 0x18c0b3d8f UIApplicationMain + 363
at 22 SwiftUI 0x191814f23 <redacted> + 163
at 23 SwiftUI 0x191742e07 <redacted> + 251
at 24 SwiftUI 0x1917240f3 $s7SwiftUI3AppPAAE4mainyyFZ + 127
at 25 Debug 0x102bb918b $s15S__Debug0A5UmAppV5$mainyyFZ + 39
at 26 Debug 0x102bb926b main + 11
at 27 dyld 0x104151ce3 0x0 + 4363459811
[DEBUG] ===== FINALLY =====
@ln-12 if you have some time, can you test if the following SNAPSHOT
fixes this issue for you?
repositories {
maven("https://oss.sonatype.org/content/repositories/snapshots")
}
dependencies {
implementation("com.juul.kable:core:0.23.0-issue-339-1-SNAPSHOT")
}
Thank you!
I had the same issue and that SNAPSHOT fixes it !
I had the same issue and that SNAPSHOT fixes it !
@rafaelfrancisco-dev thanks for testing/validating the fix!
Unfortunately, I am no longer working on the project which used this library, so I can not test it additionally :/