eclipse-archived / smarthome

Eclipse SmartHome™ project
https://www.eclipse.org/smarthome/
Eclipse Public License 2.0
861 stars 787 forks source link

Bose Soundtouch - fixed an issue with async. websocket requests #6874

Closed alex-kostadinov closed 5 years ago

alex-kostadinov commented 5 years ago

When a refresh command is sent to some of the Bose's items, the following exception could be thrown:

Exception occurred while informing handler: Blocking message pending 10000 for BLOCKING
java.lang.IllegalStateException: Blocking message pending 10000 for BLOCKING
    at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.lockMsg(WebSocketRemoteEndpoint.java:130)
    at org.eclipse.jetty.websocket.common.WebSocketRemoteEndpoint.sendString(WebSocketRemoteEndpoint.java:385)
    at org.eclipse.smarthome.binding.bosesoundtouch.internal.CommandExecutor.getInformations(CommandExecutor.java:123)
    at org.eclipse.smarthome.binding.bosesoundtouch.handler.BoseSoundTouchHandler.handleCommand(BoseSoundTouchHandler.java:190)
    at org.eclipse.smarthome.core.thing.binding.BaseThingHandler.channelLinked(BaseThingHandler.java:233)
    at org.eclipse.smarthome.core.thing.link.ThingLinkManager.lambda$0(ThingLinkManager.java:300)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Basically, the issue happens because multiple threads are trying to send commands to the same remote websocket endpoint. So, in order to prevent this, we excahge the usage of void sendString(String text) throws IOException) method to Future<Void> sendStringByFuture(String text) which initiates an asynchronous transmission of a text message. However, since all places where sendStringByFuture(String text) is called are void methods, we do not need to care of getting the future and checking the progress of the transmission.

kaikreuzer commented 5 years ago

Thanks! I've also migrated this change to https://github.com/openhab/openhab2-addons/pull/4665.