164 lines
7.8 KiB
Plaintext
164 lines
7.8 KiB
Plaintext
NORM Rules
|
|
|
|
This file contains descriptions of rules used in the NRL
|
|
NORM implementation for various aspects of protocol
|
|
operation. These rules are related to the nature of the
|
|
NORM protocol and how this particular implementation
|
|
maintains protocol state.
|
|
|
|
Norm Receive Object Status Rules
|
|
====================================
|
|
|
|
When a message for a transport object is received from a
|
|
remote NORM server node, the "status" (based on the object's
|
|
transport identifier - NormObjectId)of the object is
|
|
determined so that appropriate actions may be taken by the
|
|
receiver. The possible status types include:
|
|
|
|
INVALID - the NormObjectId is out-of-range with respect
|
|
to the current state for the sender. Out-of-
|
|
range is defined as an objectId which is
|
|
excessively ordinally less than the range of
|
|
currently pending objects (or last object
|
|
successfully complete if none are pending)
|
|
Note that if the object is the _first_ object
|
|
received for the sender, it is always considered
|
|
"valid", thus establishing an initial
|
|
synchronization point for the sender (sync_id):
|
|
|
|
sender->Synchronized AND
|
|
|
|
objectId < sync_id OR
|
|
objectId > first_pending + bufferRange
|
|
(first_pending = sender->IsPending ?
|
|
first_pending : next_pending)
|
|
|
|
NEW - The objectId is greater than the range of
|
|
currently pending objects (but not too
|
|
much greater) and acceptable for reception.
|
|
Note that is the object is the _first_
|
|
received from the sender, this status
|
|
always results:
|
|
|
|
!sender->Synchronized OR
|
|
|
|
objectId >= next_pending AND
|
|
object_id - first_pending < bufferRange
|
|
(first_pending = sender->IsPending ?
|
|
first_pending : next_pending)
|
|
|
|
PENDING - The objectId corresponds to an object _within_
|
|
the range of currently pending objects for
|
|
the sender and has is marked as still pending:
|
|
|
|
sender->Synchronized AND
|
|
sender->IsPending() AND
|
|
first_pending <= objectId < next_pending AND
|
|
sender->IsPending(objectId)
|
|
|
|
COMPLETE - The objectId is within range of objects which
|
|
have been detected and is not marked as pending:
|
|
|
|
sender->Synchronized AND
|
|
sync_id <= objectId < next_pending AND
|
|
!sender->IsPending(objectId)
|
|
|
|
Note since the sequence of objectId's received from a sender
|
|
is circular, the "sync_id" will eventually need to be
|
|
updated as the sequence of objects progresses. Also note
|
|
that the "sync_id" might be adjusted depending upon the
|
|
receiver synchronisation policy. For example, if the
|
|
synchronization policy is strict, the "sync_id" will be
|
|
fixed to no less than the first object the receiver accepts
|
|
for reception (according to policies) But for a looser
|
|
policy the receiver might permit the sync_id to be
|
|
decremented to fit within the current "bufferRange". An
|
|
even looser policy would be to allow the receiver's buffer
|
|
range to grow as needed. However, for some applications,
|
|
the sender has a finite range of objects for which it
|
|
will maintain repair state.
|
|
|
|
The "bufferRange" is the range (sequential count) of objects
|
|
for which the receiver is maintaining state. That range may
|
|
be application specific and senders/receivers are anticipated
|
|
to use relatively compatible buffer ranges/sizes based on
|
|
application needs.
|
|
|
|
SENDER/RECEIVER RESOURCE MANAGEMENT
|
|
|
|
The NORM implementation restricts the server (sender) to a
|
|
user-defined, fixed amount of buffer space (memory) for storing
|
|
calculated parity segments and repair state (i.e. which
|
|
blocks/segments are pending transmission, and any pending repairs).
|
|
The client (receiver) is similarly limited, but on a "per-sender"
|
|
basis (i.e. the client allocates a fixed pool of buffer space per
|
|
sender). However, the code is designed to successfully work even
|
|
when the buffer limits are exceeded. It does this via resource
|
|
management (i.e. stealing less critical buffer resources to cache
|
|
transmit or receive repair state). The buffer space consists of a
|
|
pool of NormBlock objects (keeps send/receive state on FEC coding
|
|
blocks) and a pool of segments (vectors for buffering NORM data or
|
|
parity payloads). The server (sender) keeps pools on a "per-session"
|
|
basis and the client (receiver) keeps pools on a "per-server" basis.
|
|
The policies for managing these pools are as follows:
|
|
|
|
NORM Server (sender) resource management.
|
|
|
|
When the NORM server is transmitting ordinally new objects/ blocks (or
|
|
is required to store repair state for previously transmitted blocks
|
|
when receiving a NACK) and its block or segment pools are empty, it
|
|
will attempt to "steal" block and/or segment resources from
|
|
non-pending blocks (oldest first) of objects in its "holding queue".
|
|
The presumption is that requests for repair of oldest objects/blocks
|
|
is less likely since clients (receivers) request repair of oldest
|
|
objects first and older objects/blocks in the queue are more likely to
|
|
have already been successfully received by all of the clients. This
|
|
results in most efficient use of CPU time on the sender side when
|
|
BANDWIDTH*DELAY*LOSS product of the network topology falls well within
|
|
the buffer space limits defined for the server. NORM will still
|
|
operate successfully at extremes of bandwidth*delay*loss, but a cost
|
|
of additional CPU demand for recalculating parity repair segments.
|
|
When there are no "non-pending" blocks to steal, repairs may be
|
|
ignored, or tranmission paused, until the repair process, and
|
|
subsequent transmissions, cause blocks to be marked as non-pending (no
|
|
pending segment transmissions or repairs).
|
|
|
|
Also note the oldest object is removed from the "holding queue" when
|
|
the count of objects in the holding queue exceeds the "transmit
|
|
hold" buffer limits when a new object is queued for transmission by
|
|
the server (sender) application. When these objects are removed, any
|
|
block or segment resources used by those objects are returned to the
|
|
respective server pools. The "transmit hold" buffer limits will be
|
|
defined as the minimum of 1) total size of objects in the queue
|
|
exceeding a "maxSize" parameter, or 2) total count of objects in the
|
|
queue exceeding a "maxCount" parameter. The "maxSize" limit is
|
|
overridden if a "minCount" value of greater than one is defined. The
|
|
"transmit hold" buffer limits define how far back the NORM server is
|
|
willing/able to go to provide repair information previous to its
|
|
current oridinal transmission point.
|
|
|
|
NORM Client (receiver) resource management.
|
|
|
|
The client portion of NORM similarly has pre-determined limits on the
|
|
quantity of buffering resources (memory) it will use on a per-server
|
|
basis. Again, NORM will still successfully operate when the
|
|
bandwidth*delay*loss product of the network topology exceed these
|
|
expected/allocated buffer limits. The cost, when this occurs, is a
|
|
decrease in the repair _efficiency_ of the NORM protocol. When the
|
|
client (receiver) becomes buffer limited, it attempts to "steal"
|
|
buffer/segment resources from ordinally _newer_ objects/blocks for
|
|
which it has accumulated state (Thus giving priority to the repair of
|
|
ordinally oldest objects/blocks). When the bandwidth*delay*loss
|
|
product of the network topology causes this to occur, the result is
|
|
less efficient repair since the client will either "forget" about some
|
|
segments it has already succesfully received (when newer blocks are
|
|
"stolen") or ignore received segments for the most ordinally recent
|
|
blocks in favor of holding state for older objects/blocks.
|
|
|
|
In summary, the NORM protocol will operate most efficiently when there
|
|
is ample buffer space, but will still successfully converge when
|
|
bandwidth*delay*loss of the network reaches extremes. The amount of
|
|
memory used by NORM can be controlled by the application.
|
|
|
|
|