CloudEvent extended publish 6.3.0 — is there a guaranteed timeout, and will isSent()/isError() always eventually resolve?

Hello there,

I'm building a power-sensitive application using a Boron with SYSTEM_MODE(SEMI_AUTOMATIC) and ULTRA_LOW_POWER sleep, using the Device OS 6.3.0 extended publish CloudEvent API. I'm managing publish state with a non-blocking FSM that polls isSent() and isError() each loop() tick after making a publish request.

The documentation states that the CloudEvent must remain allocated until the publish completes by success or failure, but does not address whether completion is guaranteed. My core question is:

Is it guaranteed that a CloudEvent publish will always resolve to either isSent()==true or isError()==true, within a specified timeout time?

Specifically I'd like to understand:

  1. Is there an internal Device OS timeout after which a publish that has neither succeeded nor failed will be resolved to isError()==true? If there is a timeout, does it depend at all on payload size?

  2. If the connection drops after Particle.publish() is called, does Device OS retry the publish after reconnecting and eventually resolve the CloudEvent one way or another (including maybe applying the timeout if any)?

  3. Clearly we should check Particle.connected() before making the publish call, but I’m intrigued by what happens if the connection was never established, or drops before the publish call: Does the CloudEvent resolve immediately to isError()==true, or does it remain unresolved until the next connection, or (probably unlikely) does the Device OS automatically try to connect?

  4. We are using Particle.setDisconnectOptions(CloudDisconnectOptions().graceful(true).timeout(timeoutMs)) to allow in-flight publishes to complete before disconnecting. Does this graceful timeout interact with CloudEvent resolution — specifically, does it guarantee that any pending CloudEvent will resolve to isSent() or isError() within the specified timeout window? Or does it only apply to the legacy publish API? What would be an appropriate timeoutMS to use?

The reason all this matters is that I need to know whether to implement my own timeout in the FSM before allowing the device to sleep. If Device OS guarantees that isSent() or isError() will always eventually become true within a bounded time — whether through its own internal timeout or via the graceful disconnect timeout — I can rely on that. If not, I need a user-implemented timeout to prevent the FSM blocking indefinitely before sleep, which in a power-sensitive application could mean never sleeping at all.

Thank you!

I don't currently know the precise answer to your question, but I believe that in general, the failure indication should occur at the CoAP timeout, which is around 20 seconds.

The part where things get messier is if the system thread is blocked. Because the sending occurs in the system thread, if the event sending cannot start, the timeout won't start, either. However if you are in this theoretically possible but unusual state, other things will also start behaving oddly. This includes your graceful cloud disconnect.

Having a safety timer at 30 seconds in case you do not get a callback would be a reasonable safety check that is unlikely to trigger but could prevent getting stuck for a long period of time.

Thank you! It’s good to know you expect resolution within about 20sec (significantly shorter than I thought might be the case), but I will implement my own timeout as you suggest to catch any rare / unexpected case.