Limiter
A limiter block places a cap on the number of packets allowed to be sent downstream at any given time. It is usually inserted between a Multicast block and a Consumer block (and in general before any IPC blocks transmitting to the consumer).
If a new packet arrives and the current number of downstream packets is at the capacity, the packet is returned upstream immediately without reaching the consumer. This is similar to frame-skipping that can be invoked by a Mailbox queue block attached to the consumer. However, in this case the skipping can occur in the producer application rather than in the consumer. When a consumer at capacity returns a packet for reuse it can then receive a new packet.
A Limiter block does not interact with any other Limiter blocks used with other consumers. Each independently imposes its own limit on what is downstream and not affected by the operations of any other limiter.
In addition, when using a mailbox queue, the consumer application must be capable of dealing with skipped frames. Typical consumers may not be aware of skipped frames and operate on the frame they receive without regard to previous frames. Where consumers need to know that a frame is missed the application suite must include a sequence number, timestamp, or other identifying information in the packet data.
Since faulty consumers may take some packets out of service, the application may need to allocate additional total packets to ensure that there are enough left for the producer and remaining consumers to use if one consumer reaches its cap and never returns any packets again.
ReturnSync
A ReturnSync block addresses security and robustness with multicast streams. A ReturnSync block can be inserted anywhere in the stream between the Producer and Consumer blocks, but its primary intent is to be inserted between a Multicast block and a Consumer block, and downstream of a Limiter block for that consumer. That is, if a producer application was concerned about one or more consumer applications generating unreliable fences, they can choose to add ReturnSync blocks to safeguard against them. This will isolate any packets with bad fences in the branch for an untrusted consumer, preventing the producer from getting stuck waiting for them.
A ReturnSync block waits for fences for each received packet from downstream before sending it upstream. If fences for the received packet are already expired or empty, then it returns the packet upstream immediately. If not, it places the packet in the queue then trigger a thread spawned by this block to manage the fence waiting before sending the packet upstream. This type of block is useful if there are blocks upstream that require synchronous access of packet data.PresentSync
For symmetry, a PresentSync block is added, which does the waiting for fences for each received packet from upstream before sending it downstream. The block spawns a thread which waits for fences in the order of the packets received and send them downstream once fences are reached.This type of block is useful if there are blocks downstream that require synchronous access of packet data.
For example, a PresentSync block can be inserted between the Producer and the memory boundary IPC block, to keep packets from being queued for sending until their contents are ready, primarily when the memory boundary IPC block uses a mailbox queue.