iceoryx: Possibility to block the publisher when subscriber queue is full
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
- increase the frequency of the subscribing application if it operates in polling mode
- increase the queue size for the subscriber
- 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
ChunkDistributorhttps://github.com/eclipse-iceoryx/iceoryx/pull/663#discussion_r606655415 - Fix
TriggerQueuehttps://github.com/eclipse-iceoryx/iceoryx/pull/663#discussion_r606653889 -
Ctrl+Con an application with an publisher blocked by a slow subscriber doesn’t shut down when a signal handler is installed; this is due to thewhile (!remainingQueues.empty())inChunkDistributor::deliverToAllStoredQueueswhich is not stopped whenSIG_TERMhas a custom signal handler- a
Runtime::unblockShutdowncould 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)
- a
- An application with a blocked publisher slows down the RouDi shutdown due to the 45s
processKillDelayinRouDi::shutdownmethod- after
m_prcMgr->requestShutdownOfAllProcesses();RouDi has to make all the publisher stop offering so that the discovery loop can remove the subscriber queues from theChunkDistributorof the publisher
- after
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 17 (16 by maintainers)
Commits related to this issue
- iox-#615 add option for publisher and subscriber Signed-off-by: Marika Lehmann <marika.lehmann@apex.ai> — committed to ApexAI/iceoryx by FerdinandSpitzschnueffler 3 years ago
- iox-#615 Mark places on where to store and compare QueueFullPolicy Signed-off-by: Simon Hoinkis <simon.hoinkis@apex.ai> — committed to ApexAI/iceoryx by mossmaurice 3 years ago
- iox-#615 Add delivery queue full policy to base port and let RouDi compare it in the discovery loop — committed to ApexAI/iceoryx by mossmaurice 3 years ago
- iox-#615 integrated trigger queue Signed-off-by: Christian Eltzschig <me@elchris.org> — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- Merge branch 'iox-#615-block-publisher-when-subscriber-queue-full' of github.com:ApexAI/iceoryx into iox-#615-block-publisher-when-subscriber-queue-full — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- iox-#615 Extend base port test — committed to ApexAI/iceoryx by mossmaurice 3 years ago
- iox-#615 trigger queue integrated in variant queue Signed-off-by: Christian Eltzschig <me@elchris.org> — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- Merge branch 'iox-#615-block-publisher-when-subscriber-queue-full' of github.com:ApexAI/iceoryx into iox-#615-block-publisher-when-subscriber-queue-full — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- iox-#615 added blocking test and adjusted overflow test Signed-off-by: Christian Eltzschig <me@elchris.org> — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- iox-#615 refactored and cleaned up variant queue Signed-off-by: Christian Eltzschig <me@elchris.org> — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- iox-#615 Extend PortManager test Signed-off-by: Simon Hoinkis <simon.hoinkis@apex.ai> — committed to ApexAI/iceoryx by mossmaurice 3 years ago
- iox-#615 Move blocking policies from BasePort to Publisher/SubscriberPort Signed-off-by: Simon Hoinkis <simon.hoinkis@apex.ai> — committed to ApexAI/iceoryx by mossmaurice 3 years ago
- iox-#615 extend getMiddlewareSubscriber/Publisher and processMessage, add tests Signed-off-by: Marika Lehmann <marika.lehmann@apex.ai> — committed to ApexAI/iceoryx by FerdinandSpitzschnueffler 3 years ago
- iox-#615 wrong value returned on overflowing push in 1:n sofi Signed-off-by: Christian Eltzschig <me@elchris.org> — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- Merge branch 'iox-#615-block-publisher-when-subscriber-queue-full' of github.com:ApexAI/iceoryx into iox-#615-block-publisher-when-subscriber-queue-full — committed to ApexAI/iceoryx by elfenpiff 3 years ago
- iox-#615 rename base options Signed-off-by: Marika Lehmann <marika.lehmann@apex.ai> — committed to ApexAI/iceoryx by FerdinandSpitzschnueffler 3 years ago
- Merge branch 'iox-#615-block-publisher-when-subscriber-queue-full' of github.com:ApexAI/iceoryx into iox-#615-block-publisher-when-subscriber-queue-full — committed to ApexAI/iceoryx by FerdinandSpitzschnueffler 3 years ago
- iox-#615 fix include paths Signed-off-by: Marika Lehmann <marika.lehmann@apex.ai> — committed to ApexAI/iceoryx by FerdinandSpitzschnueffler 3 years ago
- iox-#615 invalid assumption for subscription state in PortMangerTest Signed-off-by: Michael Poehnl <michael.poehnl@apex.ai> — committed to ApexAI/iceoryx by budrus 3 years ago
- iox-#615 extension of publisher port test Signed-off-by: Michael Poehnl <michael.poehnl@apex.ai> — committed to ApexAI/iceoryx by budrus 3 years ago
I would suggest the following approach.
blockingPush,timedPush,tryPushas pendant toblockingPop,timedPop,tryPopI_WANT_IT_ALLDONT_STOP_ME_NOWor is set toTHE_SHOW_MUST_GO_ON@budrus with an impossible task
@elBoberido @mossmaurice. I would also vote for option 1. I fear that ugly things could happen if we do another bookkeeping. having a
runtime.shutdown()that sends a command over UDS and ends up in doing the things on RouDi side you made to solve the challenge their is maybe the best for now. So we have a bit of reuse. Setting something in an individual publisher to release it feels even more ugly and more ideas I do not haveYes, it’s kind of hacky but I wouldn’t do it in only in the
release_1.0branch in order to keep the branches in sync for as long as possible and also to not keep this regression in master.This is the make it work -> make it beautiful -> make it fast cycle 😉
@ithier at least you realized that I got the hardest job