PublishQueuePosixRK - ensuring events sent before going to sleep

Are there any recommended settings / approach to handle the following situations with a WiFi or Ethernet network connection (P2 and Device OS 6.3.0):

  1. System Reset
  2. Sleep (stop)

To handle 1. I have this near the start of setup(). Not sure about the timeout value.
Particle.setDisconnectOptions(CloudDisconnectOptions().graceful(true).timeout(5000));

For 2. When calling System.sleep(WKP, RISING); I am seeing the following log output:

0034949692 [system] INFO: Cloud: disconnecting
0034949715 [comm] INFO: Waiting for Confirmed messages to be sent.
0034950716 [comm] INFO: All Confirmed messages sent: client(yes) server(yes)
0034950743 [system] INFO: Cloud: disconnected
0034950773 [system.nm] INFO: State changed: IP_CONFIGURED -> IFACE_REQUEST_DOWN
0034950813 [net.ifapi] INFO: Netif wl3 state DOWN
0034950832 [hal] INFO: DNS server list changed
0034950834 [hal] INFO: DNS server list changed
0034950838 [system.nm] INFO: State changed: IFACE_REQUEST_DOWN -> IFACE_DOWN
0034950843 [net.rltkncp] WARN: NCP connection state event ignored, netif not up
0034950846 [ncp.rltk.client] WARN: Disconnect linkError=00000000 reason=0000:
0034950850 [net.ifapi] INFO: Netif wl3 link DOWN, profile=NONE
0034950852 [hal] INFO: DNS server list changed
0034950854 [hal] INFO: DNS server list changed
0034950856 [system.nm] INFO: State changed: IFACE_DOWN -> DISABLED

However, the event queue is not being cleared before disconnecting. Is the best way to wait for an empty queue before calling System.sleep() or is there some other cunning approach?

Last question, is PublishQueuePosixRK still being developed/maintained given the PublishQueueExtRK library?

Both PublishQueuePosixRK and PublishQueueExtRK require that you use the getCanSleep() method to see if the queue is empty before going to sleep.

Once 6.3.0 is widely deployed I'll probably stop updating PublishQueuePosixRK.

At what point should I consider a switch from PublishQueuePosixRK to PublishQueueExtRK - I have got a product launch soon.

Would a snippet to use getCanSleep() look like this

    if (Particle.connected())
    {
        while (!PublishQueuePosix::instance().getCanSleep())         //wait for the queue to empty before going to sleep
        {
            delay(100);
        }
    }

Or is waitFor(PublishQueuePosix::instance().getCanSleep(),2s); better?

Ideally you should be using a state machine, but you at least need to do this, otherwise it will wait forever:

while (!PublishQueuePosix::instance().getCanSleep())         //wait for the queue to empty before going to sleep
        {
            PublishQueuePosix::instance().loop();
            delay(1);
        }

You probably want to have some additional logic so you can abandon waiting after a period of time if something goes wrong.

I understand the timeout, are you including the check for there being a cloud connection in the getCanSleep() or that is what the timeout is there to handle as well as other conditions?

getCanSleep() returns true if the queue is empty, regardless of cloud connectivity status. You can implement your own logic around it. which is typically if you not able to connect for a period of time, go to sleep and try later.

However, my recommendation for a timeout is for general safety, if there's some edge condition that was not anticipated. You should never have a loop that depends on some external logic that only has one way to exit, in case that logic get stuck somehow.

1 Like