Skip to content

gopherjs deadlock with mqtt/websocket library port #1106

Closed
@Bluebugs

Description

@Bluebugs

Trying gopherjs with mqtt/websocket in both Chrome and Firefox as in this branch: https://github.com/Bluebugs/paho.mqtt.golang/tree/bugs/gopherjs-deadlock lead to a deadlock in the following function: https://github.com/Bluebugs/paho.mqtt.golang/blob/bugs/gopherjs-deadlock/token.go#L101 when called from https://github.com/Bluebugs/paho.mqtt.golang/blob/bugs/gopherjs-deadlock/net.go#L216 .

I tried to write a test that would trigger the problem, but couldn't figure out a way for gopherjs test to execute it as it seems some syscall are missing in that case when doing websocket related traffic.

Instead I added a small example in cmd/websocket that work fine with go run or inside a browser with go wasm target, but fail with gopherjs serve and endup in a dead lock. It use mosquitto public mqtt server which provide websocket interface.

A working output would look like:

[client]   Connect()
[store]    memorystore initialized
[client]   about to write new connect msg
[client]   socket connected to broker
[client]   Using MQTT 3.1.1 protocol
[net]      connect started
[net]      received connack
[client]   startCommsWorkers called
[client]   client is connected/reconnected
[net]      incoming started
[net]      startIncomingComms started
[net]      outgoing started
[net]      startComms started
[client]   startCommsWorkers done
[pinger]   keepalive starting
[net]      outgoing waiting for an outbound message
[client]   exit startClient
[client]   enter Subscribe
[net]      logic waiting for msg on ibound
[net]      startIncomingComms: inboundFromStore complete
[net]      logic waiting for msg on ibound
[client]   SUBSCRIBE: dup: false qos: 1 retain: false rLength: 0 MessageID: 1 topics: [gopherjs/tests/attributes]
[client]   sending subscribe message, topic: gopherjs/tests/attributes
[net]      obound priority msg to write, type *packets.SubscribePacket
[client]   exit Subscribe
[net]      outgoing waiting for an outbound message
[net]      startIncoming Received Message
[net]      startIncomingComms: got msg on ibound
[net]      startIncomingComms: received suback, id: 1
[net]      startIncomingComms: granted qoss [1]
[net]      logic waiting for msg on ibound
[client]   enter Publish
[client]   sending publish message, topic: gopherjs/tests/attributes
[net]      obound msg to write 2
[net]      obound wrote msg, id: 2
[net]      outgoing waiting for an outbound message
[net]      startIncoming Received Message
[net]      startIncomingComms: got msg on ibound
[net]      startIncomingComms: received publish, msgId: 1
[net]      logic waiting for msg on ibound
[client]   enter Unsubscribe
[client]   sending unsubscribe message, topics: [gopherjs/tests/attributes]
[client]   exit Unsubscribe
[net]      putting puback msg on obound
[store]    memorystore del: message 1 was deleted
[net]      done putting puback msg on obound
[net]      obound priority msg to write, type *packets.UnsubscribePacket
[net]      outgoing waiting for an outbound message
[net]      obound priority msg to write, type *packets.PubackPacket
[net]      outgoing waiting for an outbound message
[net]      startIncoming Received Message
[net]      startIncomingComms: got msg on ibound
[store]    memorystore del: message 2 was deleted
[net]      startIncomingComms: received puback, id: 2
[net]      logic waiting for msg on ibound

While a non working one will look like :

[client]   Connect()
[store]    memorystore initialized
[client]   about to write new connect msg
[client]   socket connected to broker
[client]   Using MQTT 3.1.1 protocol
[net]      connect started
[net]      received connack
[client]   startCommsWorkers called
[client]   client is connected/reconnected
[net]      incoming started
[net]      startIncomingComms started
[net]      outgoing started
[net]      startComms started
[client]   startCommsWorkers done
[client]   exit startClient
[pinger]   keepalive starting
[net]      logic waiting for msg on ibound
[net]      startIncomingComms: inboundFromStore complete
[net]      logic waiting for msg on ibound
[net]      outgoing waiting for an outbound message
[client]   enter Subscribe
[client]   SUBSCRIBE: dup: false qos: 1 retain: false rLength: 0 MessageID: 1 topics: [gopherjs/tests/attributes]
[client]   sending subscribe message, topic: gopherjs/tests/attributes
[client]   exit Subscribe
[net]      obound priority msg to write, type *packets.SubscribePacket
[net]      outgoing waiting for an outbound message
[net]      startIncoming Received Message
[net]      startIncomingComms: got msg on ibound
[net]      startIncomingComms: received suback, id: 1
[net]      startIncomingComms: granted qoss [1]
[client]   enter Publish
[client]   sending publish message, topic: gopherjs/tests/attributes
[net]      obound msg to write 2
[net]      obound wrote msg, id: 2
[net]      outgoing waiting for an outbound message
[net]      startIncoming Received Message
[pinger]   ping check 4.822
[pinger]   ping check 9.822
[pinger]   ping check 14.821
[pinger]   ping check 19.819
[pinger]   ping check 24.819

As you can see in the non working case, it never go into [net] logic waiting for msg on ibound after [net] startIncomingComms: granted qoss [1].

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions