SYSTEM_THREAD(ENABLED); still blocks Publish

I need for my code to continue running through a “Publish” even if there is no cell service.

I added SYSTEM_THREAD(ENABLED); just above void setup() in the code.

When there is connectivity, the program runs normally. However, if I disconnect the antenna (to simulate no cell service), the next time the program tries to do a Publish, the Electron blinks for “Connecting to Network”, and the firmware still blocks on the Publish - just as if the SYSTEM_THREAD statement wasn’t there. My publish statement is:

ShowStatus("Connecting     ", 7);
digitalWrite(ledPin, HIGH);
if (Particle.publish("RV2Startup",mySend, PRIVATE) ) {
  ShowStatus("Waiting Reply", 7);
} else {
  ShowStatus("No Connection", 7);
}

“ShowStatus” is a function that displays text on a small OLED screen, and neither option on the “IF” executes.

I’m at firmware version 0.7.0.

Any ideas?

@Iras, take a look at using the NO_ACK flag with Publish. This will allow Publish to continue execution without waiting on an ACK from the Cloud.

Also, in 0.7.0 and later you can’t check the result from publish if you don’t want to block. The reason is that publish actually returns a particle::Future<bool> now. If you discard the result, the call doesn’t block on the future. If you do check the result, the future will block until the result is available, which takes the timeout for connecting to the cloud and attempting to publish.

1 Like

I will try NO_ACK, but then what’s the difference between using NO_ACK and SYSTEM_THREAD(ENABLED)?

@Iras, @rickkas7 points out that if you don’t read the return from Publish, it will not block even with ACK (default). Using SYSTEM_THREAD(ENABLED) has no effect here since blocking is a logical consequence of waiting on the Cloud ACK in the user thread. There is not mechanism for responding to the Future returned by Publish (eg. callback) so it blocks. So, you can either ignore the Future (with no guarantee that Publish was actually ACKed) or use NO_ACK to prevent blocking.

1 Like

I'm not sure that's true. I originally wasn't using SYSTEM_THREAD(ENABLED), and was not checking the result of the publish, and didn't specify anything regard ACK or NO_ACK, and it blocked on the Publish. All I had was:

Particle.publish("RV2Startup",mySend, PRIVATE)

originally and it blocked when cell service was lost. That was what started me down the road to SYSTEM_THREAD(ENABLED) and, per suggestion above, NO_ACK.

@Iras, are you using system firmware 0.7.0 or later? @rickkas7, is your statement regarding the Future predicated on SYSTEM_THREAD(ENABLED)?

Yes, 0.7.0 firmware

Correct. If you are not using SYSTEM_THREAD(ENABLED), all calls will block.

If you are using SYSTEM_THREAD(ENABLED), the call actually runs on the system thread, however, if you test the result of Particle.publish in 0.7.0 and later, the future will block the application loop thread until the operation completes on the system thread, because there’s no other way to get the boolean success result unless you wait to see if the operation actually succeeded.

3 Likes