question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Coroutines — Large NOTIFY gets unbearably slow

See original GitHub issue

Original topic:

Large NOTIFY gets unbearably slow

Summary

In my project, I’m connecting to a device that transfers a relatively large amount of data (up to 16MB) via a characteristic’s NOTIFY. The equivalent code on iOS works fine, however on Android, using RxAndroidBle, it slows down to an unbearably slow speed the more data it receives.

MTU is set properly, and ends up being 247 (250 - 3b header), which is the maximum supported on the devices. iOS uses a lower MTU, 162 (165 - 3b header).

I’ve tried requesting lower MTU to see if it helps, to no avail.

The code is pretty simple, after the connection is established (using ReplayingShare), it creates the subscription via setupNotification.

The transfer starts out with pretty decent speed, 1MB takes around 1 minute to sync, however around 3MB received, the speed drops, and the next MB takes 2 minutes, the next MB then 3-4 minutes, and the transfer time keeps creeping up.

Initially I thought it was my fault, as I was storing the data the worst possible way:

var rawData = ByteArray(0)

// in the subscribe block:
rawData += it

However even after removing the storage of the data, the slow-down still happens.

Library version

1.10.4

Preconditions

Steps to reproduce actual result

Not sure if it’s reproducible as I have not seen any devices that use a similar technique to transfer data stored on them.

Actual result

The speed of the transfer drops exponentially (or rather, the amount of time required to transfer the same amount of data increases exponentially). The time between the logged Transferred $x out of $y events also increases (initially it’s around 10-20ms between messages, which increases to around 100-120ms by the time I transferred ~3MB).

Expected result

Speed should be somewhat constant, with minimum variation between the times required to transfer the same sized blocks.

Minimum code snippet reproducing the issue

var transferred = 0
connection
    ?.flatMap { it.setupNotification(id) }
    ?.flatMap { it }
    ?.subscribe(
        {
            transferred += it.size
            logger.i("[DataSync] Transferred $transferred out of $available")
        },
        { logger.e(it, "[DataSync] Exception happened") },
        { logger.i("[DataSync] Transfer complete!") }
    )
    .addToEventStream(eventStream)

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:31 (16 by maintainers)

github_iconTop GitHub Comments

1reaction
fonix232commented, Nov 29, 2019

Ah, indeed you’re right. Multiple sources suggested that writing the descriptor with BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE value will also trigger setCharacteristicNotification() internally. This is not the case. All is working fine now, I will be reporting back sometime next week to see if this actually improves transfer speeds!

0reactions
dariuszseweryncommented, Dec 23, 2019

Two weeks have passed. I am closing this issue. Still — feel free to share a minimal project that displays the issue — I could then start digging /experimenting from there and reopen the topic. Although it seems not related directly to the library, having experience with coroutines could help in the future or give hints whether a coroutines API is feasible for BLE.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Coroutines — Large NOTIFY gets unbearably slow · Issue #651
In my project, I'm connecting to a device that transfers a relatively large amount of data (up to 16MB) via a characteristic's NOTIFY...
Read more >
Kotlin coroutines slow start - Stack Overflow
I think it actually explains cold starts. OP said there are multiple processes like this invoked at one. If their number is bigger...
Read more >
Why are my coroutines slow? | The Dev Tavern
In this post, we will discover the consequences of making blocking calls inside coroutines, what strategies we can use to deal with them, ......
Read more >
Slowdown with coroutines - Unity Forum
The problem is when getting close to the surface, the number of subdivisions is very large, and so many coroutines at once makes...
Read more >
Improve app performance with Kotlin coroutines
Kotlin coroutines enable you to write clean, simplified asynchronous code that keeps your app responsive while managing long-running tasks ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found