eclipse-iceoryx / eclipse-iceoryx/iceoryx
Possibility to block the publisher when subscriber queue is full
- Dominant language
- C++
- Stars
- 2.2k
- Forks
- 492
- Avg merge
- 18h 57m
- Merged PRs (30d)
- 1
Description
## Brief feature description
Today our default is to use an "overflowing queue" for the subscribers. If the subscriber does not consume fast enough we start loosing samples. An option would be nice to block the publisher in this case for ensuring that no samples are lost.
## Detailed information
The overflowing queue starts to drop the oldest sample in case of an overflow, so technically it behaves like a ring buffer. In many use cases this is fine as we want to have a "provide the last X samples" contract. E.g. if a subscriber is only interested in latest greatest data, they can set the queue size to 1 and we don't waste memory chunks with samples that are not interesting for the subscriber. We often also do not want to have an interference from a subscriber back to a publisher. So if the subscriber is not fast enough to consume all samples solutions could be
1. increase the frequency of the subscribing application if it operates in polling mode
2. increase the queue size for the subscriber
3. decrease the runtime for the subscribing application
But there also might be use cases where it is fine to slow down the publisher to ensure that no data is lost in our system. The solution would be to block the `publish()` call when we detect a queue overflow until the subscriber popped samples and there is again a free slot in the queue. Sure, this has an influence on the publishing applications ans also other subscribers that are connected to this publisher. This is comparable to the DDS history QoS KeepAll. The normal behavior with our overflowing queue is comparable to the DDS history QoS KeepLastX
## ToDo
When implemented implement the following integration tests:
- [ ] Modified icedelivery where subscriber acquires no samples until publisher blocks. When publisher blocks press CTRL-c (for both sides)
- [ ] Unsubscriber subscriber when publisher is in blocking push.
- [ ] Destroy subscriber object when publisher is in blocking push.
- [ ] Subscribe new subscriber when publisher is in blocking push.
- [ ] Unsubscribe different subscriber when publisher is in blocking push with another subscriber.
- [ ] Optimization in `ChunkDistributor` https://github.com/eclipse-iceoryx/iceoryx/pull/663#discussion_r606655415
- [ ] Fix `TriggerQueue` https://github.com/eclipse-iceoryx/iceoryx/pull/663#discussion_r606653889
- [x] `Ctrl+C` on an application with an publisher blocked by a slow subscriber doesn't shut down when a signal handler is installed; this is due to the `while (!remainingQueues.empty())` in `ChunkDistributor::deliverToAllStoredQueues` which is not stopped when `SIG_TERM` has a custom signal handler
- a `Runtime::unblockShutdown` could be implemented
- this could call stop offer on all the publisher
- it must be carefully checked what the stop offer call does since only a limited number of functions are allowed to be called in the signal handler (https://man7.org/linux/man-pages/man7/signal-safety.7.html)
- [x] An application with a blocked publisher slows down the RouDi shutdown due to the 45s `processKillDelay` in `RouDi::shutdown` method
- after `m_prcMgr->requestShutdownOfAllProcesses();` RouDi has to make all the publisher stop offering so that the discovery loop can remove the subscriber queues from the `ChunkDistributor` of the publisher
Contributor guide
Assessment
This issue has not been assessed yet.