Skip to content

Holon Cache

Steve Melville edited this page Nov 28, 2023 · 6 revisions

Holon Cache Manager

The MAP Holons Data Manager tries to minimize fetches to backing stores. It does this by, as much as possible, operating on SmartReferences to holons, not the holons themselves. And when retrieval of holon state from the persistence tier IS required, cache the holon's state in the HolonCache so that it needn't be retrieved more than once.

The HolonCacheManager maintains an in-memory, server-side, read-through cache (see Cache Strategies) for both local and external holons and mediates all fetches from the (local or external) backing stores.

pub struct HolonCacheManager {
     local_cache: HolonCache,
     external_caches: BTreeMap<OutboundProxyId, HolonCache>,
}

This component allows Holon Records to be cached and retrieved via their HolonReference. Because holochain records are immutable, the cache can be shared across sessions, while still remaining stateless from a client perspective. In other words, the cache can persist beyond the lifetime of a request on the MAP Holons component (though the feasibility and design for doing this in a Conductor process is TBD).

A key advantage of having immutable records, is that we don't have to worry about cached records becoming inconsistent with their backing store. This means, for example, it is not necessary to maintain a 'dirty bit'. The primary motivation for dropping cached records is to stay within memory constraints. We probably don't need to worry about this in the prototype, but a Time to Live (TTL) cache replacement policy can be implemented. Each cache entry includes a ttl property that represents the time during which the holon is intended to remain in the cache. It is set when the holon is fetched (and could be different for different holon types if we added a ttl_policy to HolonDescriptors).

pub struct HolonCache {  
    fetcher: Dance, // the Dance that can be used to fetch records from the backing store for this cache    
    map: HashMap<HolonId,CachedHolon>,
}  

pub struct CachedHolon {  
     id: HolonId,
     til: Timestamp,
     holon: Option<Holon>, // why Option?
}


HolonCacheManager provides the following public methods:

 `get(reference:HolonReference)-> Result<Holon>` -- returns a clone of the referenced holon 
 `bulk_get(references:Vec<HolonReference>)-> Result<Vec<Holon>>` -- returns a vector of clones of the referenced holons,

The get method:

  • matches the HolonReference to determine which cache to search (local or external)
  • searches the appropriate cache for the HolonId within the HolonReference.
  • If not found,
    • using the fetcher for that cache to fetch the record from its local HolonSpace or external HolonSpace
    • adds the fetched record as a CachedHolon element to the appropriate cache.
  • A clone of the Holon is returned.

The bulk_get method uses similar logic, but for a vector of HolonReferences. Note that the vector of HolonReferences supplied to this method may involve a mix of HolonSpaces. For efficiency, it may be desirable to first group the references by proxy_id so that only a single bulk_fetch need be performed against each backing store.

HolonCacheManager implements the following private methods:
load(holon_record : Record)-> Result<Holon> -- loads the specified record into the cache, if it is not already loaded.

 `prune_all() -> Integer` (FUTURE) -- clears "older" records from the cache to reclaim memory and returns a count of how many records were removed. The exact method it uses to determine which (and how many) records to remove is TBD. One strategy would be to specify the how much space needs to be reclaimed via a parameter to the `compress_all` method. The cache is then sorted by `ttl`. The compress function that iterates through the sorted cache, removing the entries with the oldest `ttl` until the desired space savings has been achieved.  

 `reset_all()` -- empties all caches
Clone this wiki locally