What is wrong with storing RxBleConnection
in a variable and using it for multiple .subscribe()
s?
(...)
What does it mean to say that multiple subscriptions "introduce state", and how can this cause problems?
These two questions are almost the same.
An RxBleConnection
is an abstraction over a state in which a BLE client exchanges some handshake packets with a BLE server after which both the client and the server are considered connected. Unfortunately due to various reasons this connection can be broken at almost any time (and that happens quite often) which a single stored variable of RxBleConnection
cannot easily express in a reactive manner.
On the other hand observing RxBleDevice.establishConnection()
will propagate an error to the subscriber once the connection will get broken. Although none of the functionality that the emitted RxBleConnection
will work once the connection is broken - a saved variable of the connection will not inform about the problem when it happens.
So if a user saves an RxBleConnection
to a variable - it introduces a state in which the variable may be in and the user is responsible for propagating (clearing the variable) errors that may happen later. As an opposite subscribing to .establishConnection()
will emit an exception when the connection cannot be used.
As many of programmers may have noticed during their practice - managing state is the most common source of bugs in the applications. Reducing state is a way to mitigate the risk of bugs.
There is an excellent (but quite advanced) talk from Devoxx by Jake Wharton: Managing State with RxJava by Jake Wharton
If this is a problem, how does ConnectionSharingAdapter
solve it?
The .establishConnection()
observable does not allow to have more than one simultaneous subsription because of the stateful nature of BLE connection and communication (request-response is a well known pattern) and having more than one .subscribe()
that uses the same connection may cause interference with the other without a clear trace in the code. That is why BleAlreadyConnectedException
was introduced for users that do not follow all places in the code that use an RxBleConnection
. ConnectionSharingAdapter
was introduced as a helper for users that conciously decide to share a single connection between more than one interactor. If the RxBleConnection
gets broken the ConnectionSharingAdapter
will propagate the error to all Subscriber
s.
Is there any clean way of combining all four characteristic I/O operations into a single .subscribe()
(that won't degrade performance)?
In most situations it is possible to cleanly combine many I/Os. The above mentioned talk touches this topic. Proper combining multiple I/Os comes with a cost of additional allocations but it is rarely a problem when dealing with BLE because of the low speed of this communication channel.