What all is / can be cloud blocking?

Pardon what may be a newbie question,

Wondering, beyond some very helpful tutorials below, what all can block the Particle cloud? For example I’ve seen an app work completely fine for days on identical hardware on same OS (even with less signal) in the lab, and the SAME app be completely unresponsive in the wild (even with better signal) right from the start.

Some links for reference:
https://community.particle.io/t/particle-publish-and-blocking/42022/1
Great to know! Basically guard against publish blocking -

if (Particle.connected()) {
			Particle.publish("Event", "Data", PRIVATE);
}

https://community.particle.io/t/particle-connect-blocking-main-loop-permanently-even-with-system-thread-enabled/40690
and
https://community.particle.io/t/loop-not-getting-called-when-using-system-thread-enabled/41461/4
Also great to know, in short -

  • Put Particle.connect() in the main loop()
  • And it’s required when SEMI_AUTOMATIC, SYSTEM_THREAD_ENABLED

I gather delay() isn’t really blocking, other than that not sure what other ‘simple’ pitfalls to avoid.

1 Like

There is no exhaustive list of all calls that can block, but you should assume that any call that requires access to the cellular modem (or Wi-Fi) will block.

In your code above, Particle.connected() does not block, because it just returns a flag and does not access the modem.

As written, Particle.publish() will generally only block for up to 20 seconds because of the connected check before it. However if you don’t check for connected first, it can block for up to 10 minutes. There might be some other edge cases where really long blocking can occur.

Also, even with the connected check, the device may not realize that it has lost its connection until it tries to send, and blocking can still occur.

The two most common cases for blocking are Particle.publish() and Cellular.RSSI(). It’s because both need to access the cellular modem, which might itself be blocked trying to reconnect to cellular. The best way to avoid this unpredictable blocking is to execute these calls from a separate thread. Sometimes two threads, or sometimes you can do both on one thread. If you use other calls that access the modem like Cellular.command()those would also potentially block, as well as things that will eventually access the modem like TCP and UDP.

Hmm interesting, so like

TCPClient client;

May block, and perhaps should be in a separate thread? I recall earlier advice ‘Say no to threads’, and ‘But I really want to use threads’ haha

Creation of the TCPClient object is not blocking, but connect() is definitely blocking. If you specify the host by name its doubly blocking because of both DNS and the TCP connection. The calls that result in a read or write can also block.

The modem is blocked issue in kind of annoying for TCP. The reason is that if you are trying to publish, even from another thread, and the cloud connection is lost and is trying to reconnect, the modem could get blocked. This will prevent TCP from working, even though it’s theoretically independent from the cloud connection. This is because the modem mutex gets blocked.

Thank you!

I'm now catching up here,

Actually I’m not quite sure on Electron how to ensure TCPClient.connect() does NOT block…

You should issue the TCP client connect from a separate thread. There’s an example here: https://github.com/rickkas7/asynctcpclient

Yes this looks awesome!

Only thing is NOT made for Electron? :frowning:

Same arena (things that cause blocking), different topic - power management; does this block in any way? Like if global object or local on stack?

In particular, are there best practices in using these functions?

They’re only blocking if the system is attempting to use the PMIC at the same time. There’s a PMIC mutex, but unlike the modem mutex, it should only be blocked for very short periods of time.

The async TCP actually does work on the Electron, you just need to increase the stack size. I apparently forgot to do that and update the README.

2 Likes

Ok thank you for the notes!