Project

General

Profile

InMemoryStorage » History » Revision 22

Revision 11 (Yingdi Yu, 09/15/2014 10:28 AM) → Revision 22/28 (Yingdi Yu, 09/18/2014 04:54 PM)

# Per-application in-memory storage 

 Many NDN applications need to publish data packets. A data packet may have a FreshnessPeriod which guards indicates how long a node (local fowarders and routers) should wait after the arrival of this data before marking it as stale. As stated in NDN-TLV spec:  

 > Note that the stale data is still valid data; the expiration of FreshnessPeriod only means that the producer may have produced newer data. 

 The inconsistency between the actually validity of a data packet and its FreshnessPeriod comes from receiving too many the unpredictability of the future. 
 In some cases, the data producer cannot predict when a data packet will be replaced by a new version of data packet.  
 One extreme solution is to set FreshnessPeriod of the unpredictable data packet to 0,  
 so that whenever the data is request, the interest will be forwarded to the original producer to check whether a new version of data packet has been generated or not. 

 Fortunately, some data packets are relatively static (i.e., it occasionally changes) and can benefit from network caching. 
 The FreshnessPeriod becomes a tradeoff between network caching and data freshness. 
 As a result, during the FreshnessPeriod, the producer will not be bothered by interests for the same data packet. 
 However, producers may still after the FreshnessPeriod, when all the cached copies become stale, the producer should be prepared to receive the interests for again. 
 If, at that time, the data is still valid, the producer should return the same data packet after to refresh the FreshnessPeriod, it cached copies. 

 It seems that it is beneficial to keep a copy of the valid data packet at the producer side, otherwise the producer has to generate/sign the data packet again and again. 
 The copy of the valid data packet cannot be stored in the ContentStore of local nfd, because current ContentStore can only tell fresh or stale data, but cannot tell valid or invalid data. 
 Instead, it is better to provide the storage inside the app, i.e., in-memory storage. 

 We list several use cases of the in-memory storage. 

 ## Use cases 

 ### PIB Service 

 PIB provides the public information about identities, keys, and certificates.  
 For example, one may ask PIB for the system default key. 
 And PIB's reply should be valid until the system default key is changed.  
 Since PIB cannot predict when the system default key will be changed, 
 it is more reasonable to set a relatively short FreshnessPeriod for the reply.  
 As a result, after every FreshnessPeriod, PIB may receive an interest for the system default key, because the cached copy in ContentStore is marked as stale. 

 In this case, PIB can benefit from the in-memory storage.  
 By putting the reply into the in-memory storage, PIB can avoid repeatedly generating the same data packet. 

 ### Nack 

 When the producer want to explicitly tell consumer some data does not exist for now, it may use the nack data. 
 However, the producer may not know when the requested data will be generated.  
 With the same logic, the producer can generate a nack data with short FreshnessPeriod, 
 and put it into the in-memory storage to avoid repeatedly generating the same nack. 
 When the requested data has been generated, the producer can replace the nack with the new data in the in-memory storage. 

 ### ChronoChat 

 For chatroom discovery, each chatroom needs to publish the chatroom-info data.  
 Chatroom-info must have finite FreshnessPeriod, so that after FreshnessPeriod, the chatroom-refresh interest will reach one of the chatroom participants. 
 If the chatroom-info has not changed yet, it is not necessary to generate a new chatroom-info data. 

 The FreshnessPeriod of a chat message can be set to infinite. However, ContentStore may not guarantee to keep all the chat messages even if they are fresh. 
 An in-memory storage can help here as a guaranteed storage as long as the process is running. 

 ### NLSR 

 NLSR LSA is the same as ChronoChat chat message. 

 ### PIB Service 

 PIB provides the public information about identities, keys, and certificates.  
 For example, one may ask PIB for current certificate for a key. 
 And PIB's reply should be valid until the system default key is changed.  
 Since PIB cannot predict when the system default key will be changed, 
 it is more reasonable to set a relatively short FreshnessPeriod for the reply.  
 As a result, after every FreshnessPeriod, PIB may receive an interest for the system default key, because the cached copy in ContentStore is marked as stale. 

 In this case, PIB can benefit from the in-memory storage.  
 By putting the reply into the in-memory storage, PIB can avoid repeatedly generating the same data packet. 

 ## Design Goal 

 The goal of InMemoryStorage is to provide a common pattern for applications that need allow an application instance to keep a copy of valid data packets for a while in its own memory.  
 Here is a diagram about how The InMemoryStorage is used: 

     +------------------------------------------------------------------------+      +---+ 
     | Application                                                              |      |     | 
     |                                                                          |      |     | 
     | +-----------+ A. Insert data    +-----------------+ C. OnInterest    +---+ |      |     | 
     | |             |---------------->|                   |<---------------|     | |      |     | 
     | |             |                   | InMemoryStorage |                  |     | |      |     | 
     | |             |---------------->|                   |--------------->|     | |      |     | 
     | |             | B. Erase data     +-----------------+ D. If data       |     | |      |     | 
     | |Processing |                         |                  is found      | F | |      | N | 
     | |Logic        |                         |                              | A | |/--\| F | 
     | |             |                         | E. If data is not found      | C | |\--/| D | 
     | |             |<----------------------+                              | E | |      |     | 
     | |             |                         | F. OnInterest                |     | |      |     | 
     | |             |                         +----------------------------|     | |      |     | 
     | |             |                                                      |     | |      |     | 
     | |             |--------------------------------------------------->|     | |      |     | 
     | +-----------+        G. data is produced                             +---+ |      |     | 
     +------------------------------------------------------------------------+      +---+ useful in two general cases: 

 Typical processing could be: 

 1. app produces a * when data packet packets have been generated without incoming interest, then it could insert interest; 
 * when the lifetime of a data packet into the InMemoryStorage (Op. A).  
 2. app may specify that some interests should be answered by InMemoryStorage first, in this case,  
    app can register the corresponding prefix with a OnInterest callback, when interest is received, 
    app will lookup in longer than the InMemoryStorage first (Op. C). If data is found, it will be returned directly (Op. D). 
    If data is not found, FreshnessPeriod of the interest will be handled by the data producing logic packet. 

 For an application that may run into either of the app (Op. E). 
    When app generates the data, app two cases, it can create an InMemoryStorage instance within itself 
 and insert the data in packets into the InMemoryStorage (Op. A) and return it to face as well (Op. G). 
 3. app can also by-pass InMemoryStorage.  
 When the InMemoryStorage for some interests. For this purpose, app can simply register a prefix with a callback 
    that directly forward receives an incoming interest, the interest to the data producing logic of the app (Op. F). 
    And the generated response will be returned to face (Op. G). 
 4. If app want to delete some may first look up matched data packets from packet in the InMemoryStorage or replace some obsolete data, it can erase to avoid generating the same data packets from the InMemoryStorage (Op. B). 



 packet again.  

 Data packets in an InMemoryStorage is explicitly managed by the app.  
 A data packet can be either inserted into or erased from the InMemoryStorage.  
 In other words, the only way to change a data packet in an InMemoryStorage is to erase the data packet from the InMemoryStorage. 

 Ideally, the InMemoryStorage should find a data packet that can match the incoming interest, 
 that is, besides longest name prefix matching, the InMemoryStorage should also process selectors. 
 However, some selectors are not meaningful to the data producer (e.g., MustBeFresh). 
 Moreover, the variety of data packets at the producer side is much less than the one in the cache intermediate routers, 
 so that some selectors (e.g., ChilderSelector, Min/MaxSuffixComponents, PublisherPublicKeyLocator) may not be necessary. 
 Therefore, longest name prefix matching alone should be sufficient for InMemoryStorage in most cases. 
 And InMemoryStorage provides two types of data look up interfaces: one is by-name while the other one is by-interest. 
 The by-name method will return the data packet that can match the interest name. 
 If there are more than one matched data packet, the lower bound (the first one in canonical order) will be returned. 
 The by-interest method will start from the first data packet that matches the name prefix and apply the selectors one-by-one, 
 therefore it is not very efficient if application did not maintain the content in the InMemoryStorage very well. 

 Note that an InMemoryStorage instance is created within an application instance, and is destroyed when the application instance ends.  
 Therefore, the lifetime of the InMemoryStorage instance is no longer than the lifetime of the application instance.  
 The data packets stored in the InMemoryStorage will also be eliminated if the data packets in it are not serialized backed up in some persistent storage (e.g., hard disk, repo, etc.) before the InMemoryStorage is destroyed. 

 Also note that data in the InMemoryStorage cannot be modified unless erased. 
 This implies that a data packet is uniquely identified by its name and implicit digest, 
 so that a data packet in InMemoryStorage cannot be overwritten by another data packet with the same name. 

 
 

 ## Interface 

 The interfaces of InMemoryStorage is defined as: 

     class InMemoryStorage  
     { 
       ... 

       // required methods 
       void  
       insert(const Data& data); 

       void  
       erase(const Name& prefix); 

       shared_ptr<const Data>  
       find(const Name& name); 

       shared_ptr<const Data>  
       find(const Interest& interest); 

       // optional methods 
       const_iterator void 
       begin() const; save(const std::string& filename); // save data packets to a file in default format 

       const_iterator void 
       end() const;  
       load(const std::string& filename); // load data packets from a file in default format 
       ... 
     }; 


 

 ## NFD support 

 Since an application has already kept a copy of data packet, it should be able to inform the local daemon not to keep a copy in the content store.  
 This can be done through extending NFD local control header, but specific design is still TBD. 

 ## Discussion about FreshnessPeriod 

 As stated in NDN-TLV spec:  

 > Note that the stale data is still valid data; the expiration of FreshnessPeriod only means that the producer may have produced newer data. 

 The inconsistency between the actually validity of a data packet and its FreshnessPeriod comes from the unpredictability of the future. 
 In some cases, the data producer cannot predict when a data packet will be replaced by a new version of data packet.  
 One extreme solution is to set FreshnessPeriod of the unpredictable data packet to 0,  
 so that whenever the data is request, the interest will be forwarded to the original producer to check whether a new version of data packet has been generated or not. 

 Fortunately, some data packets are relatively static (i.e., it occasionally changes) and can benefit from network caching. 
 The FreshnessPeriod becomes a tradeoff between network caching and data freshness. 
 As a result, during the FreshnessPeriod, the producer will not be bothered by interests for the same data packet. 
 However, after the FreshnessPeriod, when all the cached copies become stale, the producer should be prepared to receive the interests again. 
 If, at that time, the data is still valid, the producer should return the same data packet to refresh the cached copies. 

 ## Reference 

 There is another type of local storage, which is different from in-memory storage, called [Managed ContentStore](http://redmine.named-data.net/projects/nfd/wiki/ManagedContentStore)