Does blocking Publish(WITH_ACK) block SoftwareTimer servicing?

I occasionally (maybe once every hour or two) have publish() calls (WITH_ACK) that take longer than two seconds to return (I’m also using PublishQueueAsyncRK, but he doesn’t do anything out of the ordinary on his calls to publish()).

I also have a hardware watchdog that needs needs to be serviced (toggle GPIO HIGH/LOW) faster than 0.5 Hz, otherwise part of my device must be reinitialized. Doing this re-initialization on a frequent basis is not an acceptable option for me unfortunately.

I’m considering setting up a simple timer to service this watchdog, but unsure if it will actually solve the underlying issue.

My interpretation of the language around software timers is that they exist as their own thread (task if speaking in FreeRTOS terminology) with separate stack, and get checked by the kernel at ~1kHz, rather than setting up a real hardware timer on the micro and throwing an interrupt.

Is the code behind Particle.publish() ATOMICly blocking, which is to say Software Timers that pop won’t be serviced until the publish() call has returned? Or is it only blocking to the calling thread?

Unfortunately I don’t have a very good mechanism to induce long publishing calls, so I can’t very easily test this myself, and the infrequency of the slow-to return publish() calls don’t give me a lot of confidence that I’ve actually fixed the issue.

Hey, I think this library runs in a separate thread, so it would not block any of your code.

I read somewhere that publishes with ACK can take up to 15 minutes in some circumstances… so, heads up.

(not sure about your other points, so I need to refrain from commenting)
Cheers!

1 Like

You could use a software timer, however the issue is if you use software timers for other purposes, since a single software timer can block all of the others since they run out of a single thread.

The PublishQueueAsyncRK publishes run out of a separate worker thread so they don’t affect software timers.

I would probably service your watchdog from a worker thread as well. It’s still possible for it to not run on schedule if code on another thread runs with interrupts disabled or has a long SINGLE_THREADED_BLOCK, but if that’s happening, then the code should be restructured to avoid blocking with thread swapping disabled.

Thanks for the insight @rickkas7 (and for the nice queue library!) and @gusgonnet. I’ll go with the belt and suspenders approach and service both from my primary application thread, as well as a timer.

I’ve discovered that my root cause of my long delays was not, in fact the async pub (as you note it runs in separate thread with non-atomic block), but rather a call to write the same JSON data to an uSD card in the same function. Seems like the appropriate thing might be to try and put said uSD I/O into a separate thread as well.

Cheers!

2 Likes